6.9 KiB
HDStack multi-process deployment
HDStack raises the aggregate hotspot capacity of one FreeDMR container by running two to five independent FreeDMR HBP workers. It does not raise the connection limit of an individual worker.
Omitting HDSTACK, or setting HDSTACK=1, preserves the existing standard
single-FreeDMR process layout. Setting HDSTACK to a value from 2 through 5
selects the generated multi-process layout:
hotspots -> proxy -> HBP workers -> no-HBP aggregator -> external FBP/OBP
|
+-> optional separate bridge.py instance
worker reports -> reporting MUX -> existing dashboard/reporting consumer
The aggregator owns all OpenBridge/FBP links from the main freedmr.cfg and
has no HBP MASTER, PEER or XLXPEER system. The optional bridge.py
process retains its own configuration and rules. The reporting MUX reads only
worker reports; aggregator and bridge reporting are not included.
Container configuration
Add these environment values to the standard freedmr service:
environment:
- HDSTACK=2
- HDSTACK_BASEID=23400
HDSTACK_BASEID is the aggregator server ID. Worker IDs are allocated by
adding their one-based worker number. For the example above, the aggregator is
23400 and the two workers are 23401 and 23402. With HDSTACK=5, worker
IDs continue through 23405.
The separate bridge.py process is enabled by default. Disable it when the
deployment does not require bridge rules or HBP peer/XLX connections:
environment:
- HDSTACK_BRIDGE=0
HDSTACK_BRIDGE accepts only 0 or 1. It affects only multi-process mode.
When disabled, no bridge configuration or rules file is required and no
bridge.py process is started. Remove or disable any aggregator OpenBridge
section intended only to connect to that bridge instance.
When the bridge is enabled, multi-process mode requires its existing inputs:
volumes:
- '/etc/freedmr/freedmr.cfg:/opt/freedmr/freedmr.cfg'
- '/etc/freedmr/freedmr-bridge.cfg:/opt/freedmr/freedmr-bridge.cfg:ro'
- '/etc/freedmr/rules-bridge.py:/opt/freedmr/rules.py:ro'
The paths can be changed with:
environment:
- HDSTACK_BRIDGE_CONFIG=/opt/freedmr/freedmr-bridge.cfg
- HDSTACK_BRIDGE_RULES=/opt/freedmr/rules.py
The main freedmr.cfg remains the sysop-facing aggregator and worker-template
configuration. It must contain one enabled [SYSTEM] stanza in MASTER mode.
All enabled and disabled OPENBRIDGE sections are copied to the aggregator;
this includes external FBP/OBP links and the configured link to bridge.py.
Other protocol systems, including [SYSTEM] and [ECHO], are not copied to
the aggregator.
Each worker receives the same [SYSTEM] policy. Only its base HBP port is
derived. Worker and aggregator configuration files are generated privately in
/dev/shm/freedmr-hdstack when the container starts. The mounted source
configuration and bridge files are not changed.
When enabled, the bridge configuration must contain the reciprocal link to the
aggregator and any PEER or XLXPEER systems used by bridge.py. Its
rules.py remains the authority for bridge routing. Bridge reporting must
either be disabled or use a port which does not collide with the worker reports
or MUX.
Worker ports
The [SYSTEM] PORT and GENERATOR values define each worker range. With the
standard values PORT=54000 and GENERATOR=100:
worker 1 -> 54000..54099
worker 2 -> 54100..54199
worker 3 -> 54200..54299
worker 4 -> 54300..54399
worker 5 -> 54400..54499
The generated ranges must fit within the UDP port range and must not collide with configured bridge, external OpenBridge or reporting ports.
Workers connect to the aggregator over generated loopback OBP v1 links. Worker
ports are 7001 through 7005; reciprocal aggregator ports are 7101 through
7105. These links are private to the container.
Session assignment
The proxy rotates new DMR IDs through the configured worker ranges. With two workers the assignments are:
new session 1 -> worker 1
new session 2 -> worker 2
new session 3 -> worker 1
new session 4 -> worker 2
Within the selected worker range, the proxy retains its existing random choice of an available generated system port.
A DMR ID remains pinned to that exact generated port for the lifetime of its active proxy session. Moving it would start a new HBP login and reset its BRIDGES and OPTIONS state. The proxy does not rebalance or fail over an active session. Once the session expires, a later login by the same DMR ID is a new assignment. Affinity is not persisted across proxy restarts.
Existing explicit proxy configurations using DestportStart and DestportEnd
continue to describe one range. The equivalent direct multi-range setting is:
[PROXY]
BackendPortRanges: [[54000, 54099], [54100, 54199]]
or:
FDPROXY_BACKEND_PORT_RANGES='[[54000,54099],[54100,54199]]'
The standard HDStack entrypoint supplies this setting automatically.
Proxy diagnostics
In multi-worker mode the proxy logs each backend number and port range during startup. With the standard two-worker layout this includes:
(PROXY)(HDSTACK) Backend:1 ports:54000-54099.
(PROXY)(HDSTACK) Backend:2 ports:54100-54199.
When FDPROXY_CLIENTINFO=1, as in the shipped Compose configuration, client
assignment and removal messages include both the backend number and exact
generated port. This makes round-robin assignment and retained session
affinity visible without enabling packet-level debug logging. Single-backend
startup output remains unchanged.
Reporting MUX
When reporting is enabled in the main configuration, worker report ports are
derived from its REPORT_PORT. With the default output port 4321:
MUX output -> 4321
worker 1 -> 4322
worker 2 -> 4323
worker 3 -> 4324
worker 4 -> 4325
worker 5 -> 4326
The MUX preserves the existing netstring reporting protocol and the main
configuration's REPORT_CLIENTS allow-list. It merges worker configuration
and bridge snapshots and relays worker bridge events. System names are
prefixed with the stable worker number to prevent collisions:
1:SYSTEM-001
2:SYSTEM-001
Only the system-name field is changed. The reporting protocol contains trusted Python pickle data and must remain on a trusted network.
A failed or malformed worker reporting source is isolated from healthy sources. Reporting failure does not affect the proxy or DMR traffic. If main reporting is disabled, worker reporting and the MUX are both disabled.
Limitations
HDStack deliberately provides no least-connections balancing, active backend failover, live migration, persistent affinity or automatic reconfiguration. A failed worker does not cause its active sessions to move to another worker. The separate bridge config and rules remain sysop-managed; the runtime generator does not create routing policy.