Skip to content

feat(server): configurable CPU budgets per tick for simulation systems#156

Merged
iverly merged 5 commits intomainfrom
feat/tick-budgets
Apr 20, 2026
Merged

feat(server): configurable CPU budgets per tick for simulation systems#156
iverly merged 5 commits intomainfrom
feat/tick-budgets

Conversation

@iverly
Copy link
Copy Markdown
Contributor

@iverly iverly commented Apr 20, 2026

Summary

  • Add cooperative TickBudget API on SystemContext — systems call ctx.budget().is_expired() to yield early when time runs out, backward-compatible with systems that ignore it
  • Per-system timing collection during both sequential and parallel dispatch, with tick overrun detection and warning log including per-system breakdown
  • Configurable [server.budgets] section with per-system overrides by name and optional default_ms fallback (config > builder declaration > unlimited)
  • Re-export TickBudget in basalt-api for plugin access

Closes #124

Test plan

  • Full workspace test suite green (0 failures)
  • clippy clean (-D warnings)
  • fmt clean
  • All existing systems continue to work without budget declarations (backward compat)
  • Manual: add [server.budgets] to basalt.toml, verify overrun logging triggers with a tight budget (e.g. physics = 0)

iverly added 4 commits April 20, 2026 20:55
Cooperative CPU budget for tick-based systems. Systems call
ctx.budget().is_expired() to yield early when time runs out.
Systems that ignore the budget run to completion (backward-compatible).

- TickBudget: tracks elapsed time against a configured limit
- SystemContext::budget(): new trait method returning &TickBudget
- SystemDescriptor.budget: optional Duration field
- SystemBuilder::budget_ms(): declares the system's time budget
…gging

Each system receives its own TickBudget based on its configured limit.
Per-system timings are collected during both sequential and parallel
dispatch. When a tick exceeds the expected duration, a warning is
logged with a per-system timing breakdown.

- Ecs: current_budget field, set_tick_duration(), tick_timings()
- run_phase: creates budget per system, records elapsed time
- dispatch_group: passes budget to ParallelSystemContext, collects timing
- run_all: checks total elapsed against tick_duration threshold
Add [server.budgets] config section for per-system budget overrides.
Operators can set budgets by system name or a global default_ms
fallback. Config overrides take priority over builder-declared budgets.

- BudgetsSection: default_ms + per-system overrides via serde(flatten)
- Server startup applies config budgets and sets tick_duration for
  overrun detection
- basalt-api re-exports TickBudget for plugin access
- basalt-testkit SystemTestContext returns unlimited budget
Required for tick overrun warning logging in the ECS dispatcher.
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'ecs'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 2.

Benchmark suite Current: 6bc54ab Previous: f1822bf Ratio
run_all_empty_systems 54.6 ns/iter (± 0.86) 26.41 ns/iter (± 0.29) 2.07

This comment was automatically generated by workflow using github-action-benchmark.

Only call Instant::now() and collect per-system timings when
tick_duration is set. This eliminates the ~25ns regression in
run_all for the common case where overrun detection is not
configured (e.g., benchmarks, tests).
@iverly iverly merged commit 42052ed into main Apr 20, 2026
22 checks passed
@iverly iverly deleted the feat/tick-budgets branch April 20, 2026 19:02
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.

feat(server): configurable CPU budgets per tick for simulation systems

1 participant