Found during the 16-way adversarial review of #115 (which fixed the exact TotalOps count; this is a different metric).
In flushPending, client.Do(radix.Pipeline(...)) returns a single error for the whole batch. That one error sets one hadError/isTimeout, which is then stamped onto the stat of every command in the window. So a pipeline flush with 1 failing + N-1 succeeding commands reports N errors, not 1.
Empirically (1 bad + 3 good HSET at --pipeline 4): Errors=4 (vs Errors=1 at --pipeline 1); the 3 good writes still land (dbsize=3) and TotalOps=4 is correct. So Errors/Timeouts and the derived error-rate % are inflated by pipeline depth, while ops/keys are correct.
Pre-existing (present before #115; #115 preserved it). Fixing it requires per-command reply-error inspection: iterate the pipeline's per-command replies (each pending[i].reply) and mark only the ones that actually returned a RESP error, rather than attributing the batch error to all. Ties into the reply-capture work in #117.
Found during the 16-way adversarial review of #115 (which fixed the exact TotalOps count; this is a different metric).
In
flushPending,client.Do(radix.Pipeline(...))returns a single error for the whole batch. That one error sets onehadError/isTimeout, which is then stamped onto the stat of every command in the window. So a pipeline flush with 1 failing + N-1 succeeding commands reports N errors, not 1.Empirically (1 bad + 3 good HSET at
--pipeline 4):Errors=4(vsErrors=1at--pipeline 1); the 3 good writes still land (dbsize=3) andTotalOps=4is correct. SoErrors/Timeoutsand the derived error-rate % are inflated by pipeline depth, while ops/keys are correct.Pre-existing (present before #115; #115 preserved it). Fixing it requires per-command reply-error inspection: iterate the pipeline's per-command replies (each
pending[i].reply) and mark only the ones that actually returned a RESP error, rather than attributing the batch error to all. Ties into the reply-capture work in #117.