Repository navigation
Conversation
…t timeout
A segmented US national run waited on each regional child with no deadline
of its own. When Modal kept re-running a child whose containers were
terminated, the parent waited until its 3,600 s Modal timeout killed it,
which also left the children running with nobody to cancel them.
On 9 October 2026 both 2023 national reports (7fa9408d and 765eefcf) hit
this: their 20 children were re-executed 180 and 131 times, none finished,
and the parents ended at 3,599.8 s (timeout) and 3,167 s ("Server has lost
track of input" from a child poll).
The runner now:
- cancels a child with no result 900 s after dispatch and respawns its
region group once, recording a segmented_national_child_respawned event
and segmented_child_retry_count;
- fails with a message naming the group when the respawn is also overdue,
fails, or the parent budget is too short to fit a retry;
- fails in-band and cancels every child when the parent budget (the
3,600 s function timeout minus a 300 s completion margin) runs out.
A unit test pins the budget constant to the run_simulation timeout in
src/modal/app.py.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ures A respawned child's original attempt was cancelled once, with errors ignored, and then dropped from tracking, so later failure paths never retried the cancel. Superseded attempts now stay tracked: they are never polled again, but every failure path and the end of collection cancel them again. The final deadline failure and parent budget exhaustion now emit structured events (segmented_national_child_timed_out and segmented_national_budget_exhausted). The respawn event and segmented_child_retry_count are recorded only after the respawn spawns. Adds tests for retrying a failed cancel, ignoring a late result from the superseded original, a failed respawn spawn, clamping a respawn's deadline to the remaining budget, and the new events. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
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.
Fixes #794
Same-Repository Draft PR Check
PolicyEngine/policyengine-sim-api, not a personal fork.Summary
Segmented US national runs had no deadline per regional child. A child that never finished held the parent until Modal's 3,600 s timeout killed it, which also left the children running. Both 2023 national reports on 9 October 2026 failed this way.
Changes to
src/modal/segmented_national.py:run_simulationtimeout minus a 300 s completion margin) runs out, the run cancels every child and then fails.segmented_national_child_respawned(warning) andsegmented_child_retry_countare recorded only after the respawn spawns. A respawn that fails to spawn is not counted.segmented_national_child_timed_out(error) is emitted when a child misses its deadline and is not respawned. Attributes:region_group,child_attempt,waited_seconds,deadline_secondsandremaining_budget_seconds.segmented_national_budget_exhausted(error) is emitted when the parent budget runs out. Attributes:region_groupsandchild_attempts(in the same order),waited_secondssince the runner started, andparent_budget_seconds.log_and_redact_exception, withregion_groupandchild_attempt.Not included
Testing
tests/test_segmented_national.py(16 cases):run_simulationtimeout insrc/modal/app.py.tests/test_canonical_spm.pybuilds a runner without its constructor and calls_collect. It now uses the new internal handle shape and sets the empty list of replaced attempts.uv run --frozen:projects/policyengine-simulation-executor749 passed, 23 skipped, 3 deselected.ruff format --checkandgit diff --checkpass.ruff checkreports no new findings. The two insegmented_national.pyare the existing pattern that ignores errors from best-effort child cancellation, now in its new location.🤖 Generated with Claude Code