Go: real parallel wave execution (opt-in) — execution parity with Python/Kotlin - #37
Merged
Merged
Conversation
The scheduler already serialized resource conflicts, but the public Go runtime executed each released wave SERIALLY. This adds actual parallel execution, mirroring the proven Python `_execute_wave` / Kotlin thread-pool pattern: a ready wave's operator invocations (the I/O wait) run concurrently behind a JOIN BARRIER, then results commit SERIALLY in deterministic node order — so world, learning, event and replay state are identical to serial; only wall-clock changes. - runtime.go: split `execute` into `invoke` (parallelizable: resolveInputs + dispatch + operator run) and `commit` / `failNode` (serial, node order). New `executeWave` runs the wave with a bounded semaphore + WaitGroup. New `maxConcurrency` field + `WithMaxConcurrency` option + `AGENTIC_OS_MISSION_CONCURRENCY` env — DEFAULT 1 (serial), parallel is opt-in (matches Python). effectiveMaxConcurrency now = min(executor pool, scheduler policy) so the two ceilings are observable (schedulerConfig gains requested_concurrency + bound_by). - executor.go: guard InMemoryOperatorClient.seen/Calls with a mutex (the handler call itself runs OUTSIDE the lock, so it parallelizes) — race-clean. Tests: concurrent==serial (same terminal state, same committed nodes, same world size) + real overlap (peak parallelism > 1) + faster; default-is-serial. Full `go test -race ./mission/` green, and the whole suite also passes with AGENTIC_OS_MISSION_CONCURRENCY=4 (every existing test correct under parallel exec). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to the Go concurrency-metadata parity (#36). That PR made the scheduler serialize resource conflicts; the public Go runtime still executed each released wave serially. This adds actual parallel execution — the last gap to full parity with the Python and Kotlin runtimes.
What
Mirrors the proven Python
_execute_wave/ Kotlin thread-pool pattern: a ready wave's operator invocations (the I/O wait) run concurrently behind a join barrier, then results commit serially in deterministic node order — so world / learning / event / replay state is identical to serial; only wall-clock changes.runtime.go:executesplit intoinvoke(parallelizable) andcommit/failNode(serial). NewexecuteWave(bounded semaphore +WaitGroup). NewmaxConcurrencyfield +WithMaxConcurrencyoption +AGENTIC_OS_MISSION_CONCURRENCYenv — default 1 (serial); parallel is opt-in, matching Python.effectiveMaxConcurrency= min(executor pool, scheduler policy), so the two ceilings are observable (schedulerConfiggainsrequested_concurrency+bound_by).executor.go: guardInMemoryOperatorClient.seen/Callswith a mutex — the handler call runs outside the lock, so it parallelizes. Race-clean.Tests
concurrency_exec_test.go: concurrent == serial (same terminal state, same committed nodes, same world size) + real overlap (peak parallelism > 1) + faster; default-is-serial. Fullgo test -race ./mission/green, and the whole suite also passes withAGENTIC_OS_MISSION_CONCURRENCY=4(every existing test correct under parallel execution).Result
Go now matches Python/Kotlin on both axes: safe-concurrency scheduling (#36) and parallel wave execution (this PR), with the same serial-by-default, opt-in posture.
🤖 Generated with Claude Code