fix(testing): filter EXECUTION ops by type, not index - #637
Conversation
| with self._state_lock: | ||
| return [ | ||
| operation | ||
| for operation in self.operations | ||
| if operation.operation_type != OperationType.EXECUTION |
There was a problem hiding this comment.
Codex AI review
P2: This lock does not synchronize with checkpoint writes. CheckpointRequestDispatcher.apply_updates() replaces and appends to execution.operations without acquiring _state_lock, so this read can still observe a partially applied checkpoint batch. Guard the entire checkpoint mutation with the same lock, or route this read through the execution worker lane, and add a concurrent checkpoint/read test.
Codex AI reviewFound one concurrency gap. Filtering is covered, but checkpoint/read synchronization is not. Reviewed commit |
Claude AI reviewThis PR reworks Assessment: no actionable findings.
Residual test risk (minor, not filed inline): Reviewed commit |
ea6d2c4 to
b4a4de5
Compare
|
the extra however, that's wider refactor beyond the scope fo this PR, and since the lock is harmless and for the sake of symmetry might as well let it stand as introduced here and then revisit clean-up opportunities for redundant locks throughout later. |
Issue #, if available: #456
Description of changes:
While looking into this I found get_assertable_operations() had a TODO on it questioning its own logic, it excludes the EXECUTION operation by just slicing off
operations[1:], assuming that operation is always first. That's true today, but it leaves a couple of things unhandled:self.operationswithout grabbing_state_lockfirst. Every other method that touches operations (get_navigable_operations,start,_end_execution, the callback completions, etc.) does take the lock, so this one stood out. Since checkpoints can land on a worker thread while this is being read, it felt worth fixing rather than leaving as a latent race.What I changed:
operation_type != OperationType.EXECUTIONinstead of slicing by index, so it excludes any EXECUTION-type entry no matter where it shows up._state_lockaround the read, matching howget_navigable_operations()already does it.Ran the full suite plus lint/type checks locally, all green:
hatch run dev-testing:test # 1379 passed
hatch fmt --check # clean
hatch run dev-testing:typecheck # clean
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.