netx/netx_api/worker.py
oliver 3a0de0d7fb Scale biz_state collects with dedicated workers and non-blocking UI poll.
Add PG claim/NE mutex, persist pool, and biz_state_worker replicas; fix double-SSH and row-count bugs; stop 32m collectNow while-loop from freezing page switches.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-22 17:00:37 +08:00

64 lines
1.7 KiB
Python

"""Background worker process for long-running schedulers.
Optional when ``NETX_RUN_INLINE_SCHEDULERS=false`` (API does not start collectors):
python -m netx_api.worker
Starts: config_sync, lldp_collect, port_traffic, fabric_reconcile tick loops.
When ``NETX_BIZ_STATE_DEDICATED_WORKERS=true`` (default), biz_state is NOT started
here — run ``python -m netx_api.biz_state_worker`` instead (start_netx does both).
UME WS / keepalive remain in the API process (token + alarm coordination).
By default the API runs collectors inline — no separate worker needed.
"""
from __future__ import annotations
import logging
import signal
import threading
import time
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s %(levelname)s %(name)s: %(message)s",
)
_log = logging.getLogger("netx.worker")
def main() -> None:
stop = threading.Event()
def _handle(_sig: int, _frame: object) -> None:
_log.info("shutdown signal received")
stop.set()
for sig in (signal.SIGINT, signal.SIGTERM):
try:
signal.signal(sig, _handle)
except Exception:
pass
from .ume_runtime import start_device_schedulers
start_device_schedulers()
try:
from .runtime_budget import log_runtime_budget
log_runtime_budget(role="worker")
except Exception:
_log.exception("worker runtime budget log failed")
_log.info(
"netx worker schedulers started (config_sync, lldp_collect, port_traffic, fabric_reconcile)"
)
while not stop.is_set():
time.sleep(1.0)
from .app_shutdown import shutdown_runtime
shutdown_runtime(reason="worker_signal")
_log.info("netx worker exiting")
if __name__ == "__main__":
main()