Add sleep/msg-recv/generator intrinsics, conversion builtins, and multiprocess tests#99
Merged
Conversation
…tiprocess tests New intrinsics: - sleep: suspend process for N milliseconds - msg-recv: receive OOB message from another process (blocking) - msg-pending: check if OOB messages are waiting (non-blocking) - break: exit loops early from within while/for bodies New builtins: - int, float: type conversion functions - is-int, is-float, is-string: type predicate functions - map, filter, reduce, range, append, reverse, nth, sort: list processing builtins - apply: call a function with a list of arguments - str-length, str-substr, str-find, str-upper, str-lower, str-split, str-join, str-trim, str-starts-with, str-ends-with, str-replace, str-to-list, str-from-list: string operations - hash-map, hash-get, hash-set, hash-keys, hash-values, hash-has, hash-remove, hash-merge, hash-count: hash map operations Generator pattern: - generator.h: lazy sequence generator with yield support - Stackless evaluator generator integration Scheduler enhancements: - Bounded message queue with configurable capacity - Queue accessor intrinsics (msg-queue-size, msg-queue-capacity) - Scheduler settings via state tree (scheduling.policy, scheduling.time-slice-ms, scheduling.max-steps-per-slice) - Process priority field and priority scheduling policy - execute_options struct for named process parameters Cross-process IPC tests: - 5 IPC tests + 3 gRPC tests for multi-process communication - Producer-consumer integration tests (12 tests) - Thread-safety tests for OOB message delivery 62 builtin + 137 intrinsic + 107 scheduler + 82 integration tests pass (388 total in this changeset).
Add comprehensive documentation for features added in this branch: - Type conversion builtins: int, float, is-int, is-float, is-string with examples and error behavior - Receiving messages: msg-recv (blocking receive with suspend semantics), msg-pending (non-blocking queue depth check) - Sleep intrinsic: sleep with duration in seconds, auto-wake - Message-driven process pattern: complete example of a receiver loop that accumulates results - Scheduler settings via state tree: load_settings() with per-scheduler and global-default resolution, published effective values - Updated architecture reference to list new intrinsics
- Fix spin loop in multiprocess tests: break when step() returns 0 (no ready process to schedule, only waiting processes remain) - Fix exit condition: use total_processes == terminated + killed instead of checking ready/running/paused (missed waiting status) - Fix deliver_to_receivers double-delivery: remove inbox.push() that duplicated message already delivered via stack patch - Fix Pipeline test scoping: replace let with set to keep loop variable in same scope as result accumulator - Add kill(child, SIGKILL) before blocking waitpid in all IPC tests
Without set_transport, msg-send delivers locally but never reaches the peer over gRPC, causing OobMessageDelivery to time out on CI.
The sleep test uses std::this_thread::sleep_for which requires <thread> and <chrono>. Linux/MSVC include these transitively but macOS Clang does not.
The state_sync_adapter attaches observers lazily via childChanged, which propagates after valueChanged has already fired. This means the very first write to a new path is invisible to the journal. The multiprocess IPC tests relied on unseed paths like producers.ready and items.ready being replicated, but those first-writes were silently dropped. Fix by: - Seeding producers.ready, items.ready, and data.ready before the scheduler runs so the adapter has observers in place. - Replacing wait_for_received(N) with polling loops that check for the actual expected state values, making the tests robust against varying mutation counts. - Increasing parent-side waitpid timeouts to 30s for CI headroom.
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.
Summary
Major expansion of the state_exec DSL with new intrinsics, builtins, generator
support, scheduler enhancements, cross-process IPC testing, and comprehensive
developer guide updates.
New Intrinsics
New Builtins
Type conversion & predicates
int,float,is-int,is-float,is-stringStandard Library Modules (new)
Module:
string(12 functions)string.length,string.substring,string.contains,string.upper,string.lower,string.split,string.join,string.trim,string.starts-with,string.ends-with,string.replace,string.char-atModule:
math(16 functions)math.sqrt,math.abs,math.floor,math.ceil,math.round,math.pow,math.log,math.sin,math.cos,math.min,math.max,math.clamp,math.pi,math.e,math.randomModule:
collections(12 functions)collections.map,collections.filter,collections.reduce,collections.zip,collections.flatten,collections.sort,collections.reverse,collections.range,collections.unique,collections.dict-keys,collections.dict-values,collections.dict-mergeGenerator Pattern
generator.h— lazy sequence generator with yield supportforloop andcollectconsumptionScheduler Enhancements
max_pending_messagesstate_exec.schedulers.<id>.max_pending_messages) and global defaults (state_exec.defaults.max_pending_messages)load_settings()with resolution order: per-scheduler -> global default -> hardcoded fallbackround_robin,priority,priority_rr)execute_optionsstruct for named process parametersCross-Process IPC Tests
Bug Fixes (CI)
step()/run(), fixeddeliver_to_receiversdouble-delivery, fixed pipeline test scoping (let->set), addedkill(child, SIGKILL)before blockingwaitpidshard_a.set_transport(&tr_a)so OOB messages reach peer over gRPC transport<thread>and<chrono>includes forstd::this_thread::sleep_forproducers.ready,items.ready,data.ready) so thestate_sync_adapterhas observers before the first write; replacedwait_for_received(N)with value-polling loops for robustnessDocumentation
STATE_EXEC_DEVELOPER_GUIDE.mdwith:Test Results
62 builtin + 137 intrinsic + 107 scheduler + 82 integration = 388 tests passing
All 14 CI jobs green (5 Linux, 4 macOS, 4 Windows, 1 clang-format).