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/hdstack.md

184 lines
6.4 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:
```text
hotspots -> proxy -> HBP workers -> no-HBP aggregator -> external FBP/OBP
|
+-> 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 separate `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:
```yaml
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`.
Multi-process mode also requires the existing separate bridge inputs:
```yaml
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:
```yaml
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.
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`:
```text
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:
```text
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:
```ini
[PROXY]
BackendPortRanges: [[54000, 54099], [54100, 54199]]
```
or:
```sh
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:
```text
(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`:
```text
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:
```text
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.

Powered by TurnKey Linux.