Make ParallelFieldGenerationRaceTest fail deterministically via CyclicBarrier#1233
Make ParallelFieldGenerationRaceTest fail deterministically via CyclicBarrier#1233Copilot wants to merge 23 commits into
Conversation
Agent-Logs-Url: https://github.com/quickfix-j/quickfixj/sessions/3cc2ab86-f818-4d6f-8294-e0d1805a7497 Co-authored-by: chrjohn <6644028+chrjohn@users.noreply.github.com>
|
@copilot please add logging output how many parallel tasks are used |
Agent-Logs-Url: https://github.com/quickfix-j/quickfixj/sessions/35104349-ab05-422d-861f-1bd35f967d72 Co-authored-by: chrjohn <6644028+chrjohn@users.noreply.github.com>
Implemented in commit |
|
@copilot make generator.parallelExecution true by default. |
Agent-Logs-Url: https://github.com/quickfix-j/quickfixj/sessions/3e8c2bde-9960-418c-9e64-f8f4d450726f Co-authored-by: chrjohn <6644028+chrjohn@users.noreply.github.com>
Done in commit |
|
@copilot parallel execution might work when calling main() of the code generator. However, it does not work when using the GenerateMojo. So the mojo needs the information for all possible executions for the various fix versions at once. Currently there are several executions in quickfixj-messages/quickfixj-messages-all/pom.xml |
Agent-Logs-Url: https://github.com/quickfix-j/quickfixj/sessions/ae17ca4b-feff-443e-a2d8-ade9e02e1fc9 Co-authored-by: chrjohn <6644028+chrjohn@users.noreply.github.com>
Implemented in commit |
|
@copilot looking good so far.
|
Agent-Logs-Url: https://github.com/quickfix-j/quickfixj/sessions/1dcb0259-f870-44c3-9304-d4eb7980b33b Co-authored-by: chrjohn <6644028+chrjohn@users.noreply.github.com>
Implemented in commit |
|
@copilot the test ParallelExecutionOptionTest.testParallelExecutionIsEnabledByDefault is flaky. It expects that the tasks always finish in the same order. Keep the assertions that verify:
|
Agent-Logs-Url: https://github.com/quickfix-j/quickfixj/sessions/58f57ec9-970d-4117-8c1f-67f4377c307c Co-authored-by: chrjohn <6644028+chrjohn@users.noreply.github.com>
| File dictionary = tempFolder.newFile("RaceCondition-" + name + ".xml"); | ||
| StringBuilder xml = new StringBuilder(); | ||
| xml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); | ||
| xml.append("<fix major=\"4\" minor=\"4\">\n"); |
There was a problem hiding this comment.
@copilot one dictonary should have minor version 2, the other (withExtraEnum) should have minor version 4.
There was a problem hiding this comment.
Addressed in commit 13e20b8. ParallelFieldGenerationRaceTest#createDictionary(...) now sets FIX minor version to 2 for the base dictionary and 4 for the withExtraEnum dictionary.
The race test relied on OS thread scheduling to produce a two-enum write after a three-enum write, causing it to pass occasionally (false negative).
Changes
createOutputStreamin an anonymousMessageCodeGeneratorsubclass; install aCyclicBarrier(2)per output-file path (stored in aConcurrentHashMap). The returnedFilterOutputStreamcallsbarrier.await()on the firstwrite(), forcing two threads to be simultaneously mid-write on the same file on every run.new MessageCodeGenerator()is used exclusively for the three-enum golden source.BrokenBarrierExceptionandTimeoutExceptionare caught so an unexpected odd-writer-count never hangs the test; those threads proceed and still exercise the race.With 16 tasks (8 two-enum, 8 three-enum) writing 1000 field files, the barrier guarantees synchronized pairs on every file — the probability of all 1000 files ending with three-enum content becomes negligible, turning a probabilistic race into a near-certain failure.