Skip to content

Serialise Recorder.record with a lock (fixes the intermittent test_concurrent_recording failure) - #99

Open
MyceliaLabsBV wants to merge 1 commit into
arcprize:mainfrom
MyceliaLabsBV:fix/recorder-write-lock
Open

MyceliaLabsBV wants to merge 1 commit into
arcprize:mainfrom
MyceliaLabsBV:fix/recorder-write-lock

Conversation

@MyceliaLabsBV

Copy link
Copy Markdown

The problem

Recorder.record writes with:

with open(self.filename, "a", encoding="utf-8") as f:
    json.dump(event, f)
    f.write("\n")

json.dump emits several small writes rather than one, so two threads appending through the same Recorder can interleave mid-line and lose or corrupt an event.

This is already visible in your own test suite. tests/unit/test_recorder.py::TestRecorderErrorHandling::test_concurrent_recording fails intermittently, typically with assert 4 == 5 — one of five events gone.

Measured, not assumed

result
current main, 20 runs 19 passed, 1 failed
with this change, 30 runs 30 passed, 0 failed

The change

Serialise the event to a single string, then perform one write under a threading.Lock.

Severity

Low in normal use — Swarm gives each agent its own Recorder and its own file, so nothing in the shipped paths shares a writer. But it is a flaky test in CI, and the race is real for anything that does share a Recorder.

Happy to drop this if you'd rather fix the test than the class, though the test looks like it is describing the intended contract.

Recorder.record wrote with

    with open(self.filename, "a", encoding="utf-8") as f:
        json.dump(event, f)
        f.write(...)

json.dump emits several small writes, so two threads appending to one
Recorder can interleave mid-line and lose or corrupt an event.

This is already visible in the suite:
tests/unit/test_recorder.py::TestRecorderErrorHandling::
test_concurrent_recording fails intermittently, typically with
"assert 4 == 5" -- one of five events lost.

Measured on the current main: 1 failure in 20 runs.
Measured with this change: 0 failures in 30 runs.

The fix serialises the event to a single string and performs one write
under a threading.Lock.

Low severity in normal use, since Swarm gives each agent its own
Recorder and its own file -- but it is a flaky test in CI, and the
underlying race is real for any code that shares a Recorder.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant