You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
FreeDMR/docs/freedmr-2/10-runtime-and-concurrency.md

2.7 KiB

Runtime and Concurrency

Decision: Do not replace Twisted as the first FreeDMR 2 architecture move.

Rationale

Current packet behaviour is subtle. Twisted's single-threaded reactor is currently a safety boundary. Replacing the event loop and the state model at the same time mixes too many changes.

The first goal is architectural clarity and testability, not event-loop novelty.

Immediate Runtime Strategy

  • Keep Twisted initially as the transport shell.
  • Use Twisted's single-threaded reactor as a safety boundary while the core is extracted.
  • Do not replace the event loop and state model at the same time.
  • Extract the protocol/routing/subscription core behind deterministic interfaces.
  • Keep packet-plane state local and deterministic.
  • No blocking work in reactor callbacks.
  • No dashboard/API/database/MQTT waits in the packet path.
  • Single-owner state is preferred.
  • Explicit messages/events are preferred over shared mutable dictionaries across threads/processes.

Eventual Capacity Strategy

FreeDMR 2 should support worker-process scaling once state ownership and message boundaries are explicit and tested.

The purpose of worker processes is not merely performance. It is also:

  • Clearer state ownership.
  • Failure isolation.
  • Safer concurrency.
  • Testable boundaries.
  • Future capacity scaling.

Prefer process/actor ownership over shared-memory no-GIL threading for authoritative routing state. No-GIL Python does not remove the need for clear ownership of mutable packet-plane state.

Offload non-packet-path work first, including reporting, MQTT publishing, global export, SQL writes, dashboard aggregation, alias refresh, analytics, and lab/codec work.

Routing-core workers are a later stage. Multi-worker sharding should only be considered after single-worker message-boundary behaviour is proven.

Twisted can remain the transport shell while reporting/export/control workers move out-of-process.

Ownership Split

Twisted parent/transport process may own:

  • UDP sockets.
  • HBP/FBP packet receive/send.
  • Timers.
  • Process supervision.

Routing core should eventually own:

  • Stream state.
  • Subscription state.
  • Dial-a-TG state.
  • Loop-control state.
  • Duplicate suppression.
  • Routing decisions.

Migration must be staged and covered by tests. FreeDMR should remain deployable on ordinary low-cost systems such as cheap VPS instances and Raspberry Pi-class hardware.

See 13-worker-process-scaling.md for the eventual worker-process capacity model.

External Databases

External stores can be useful for configuration, reporting snapshots, global lastheard, operator UI, and coordination. They should not sit in the packet hot path.

Packet-plane state should stay local and in memory unless a future design proves a bounded, non-blocking alternative.

Powered by TurnKey Linux.