Prioritize node posts in queued API updates (#107)

* Prioritize node posts in queued API updates

* run black
This commit is contained in:
l5y
2025-09-16 19:30:38 +02:00
committed by GitHub
parent 4182a9f83c
commit cffdb7dca6
2 changed files with 108 additions and 11 deletions
+60 -2
View File
@@ -23,6 +23,8 @@ entry point that performs these synchronisation tasks.
"""
import dataclasses
import heapq
import itertools
import json, os, time, threading, signal, urllib.request, urllib.error
from collections.abc import Mapping
@@ -40,6 +42,17 @@ INSTANCE = os.environ.get("POTATOMESH_INSTANCE", "").rstrip("/")
API_TOKEN = os.environ.get("API_TOKEN", "")
# --- POST queue ----------------------------------------------------------------
_POST_QUEUE_LOCK = threading.Lock()
_POST_QUEUE = []
_POST_QUEUE_COUNTER = itertools.count()
_POST_QUEUE_ACTIVE = False
_NODE_POST_PRIORITY = 0
_MESSAGE_POST_PRIORITY = 10
_DEFAULT_POST_PRIORITY = 50
def _get(obj, key, default=None):
"""Return a key or attribute value from ``obj``.
@@ -82,6 +95,51 @@ def _post_json(path: str, payload: dict):
print(f"[warn] POST {url} failed: {e}")
def _enqueue_post_json(path: str, payload: dict, priority: int):
"""Store a POST request in the priority queue."""
with _POST_QUEUE_LOCK:
heapq.heappush(
_POST_QUEUE, (priority, next(_POST_QUEUE_COUNTER), path, payload)
)
def _drain_post_queue():
"""Process queued POST requests in priority order."""
global _POST_QUEUE_ACTIVE
while True:
with _POST_QUEUE_LOCK:
if not _POST_QUEUE:
_POST_QUEUE_ACTIVE = False
return
_priority, _idx, path, payload = heapq.heappop(_POST_QUEUE)
_post_json(path, payload)
def _queue_post_json(
path: str, payload: dict, *, priority: int = _DEFAULT_POST_PRIORITY
):
"""Queue a POST request and start processing if idle."""
global _POST_QUEUE_ACTIVE
_enqueue_post_json(path, payload, priority)
with _POST_QUEUE_LOCK:
if _POST_QUEUE_ACTIVE:
return
_POST_QUEUE_ACTIVE = True
_drain_post_queue()
def _clear_post_queue():
"""Clear the pending POST queue (used by tests)."""
global _POST_QUEUE_ACTIVE
with _POST_QUEUE_LOCK:
_POST_QUEUE.clear()
_POST_QUEUE_ACTIVE = False
# --- Node upsert --------------------------------------------------------------
def _node_to_dict(n) -> dict:
"""Convert Meshtastic node or user structures into plain dictionaries.
@@ -129,7 +187,7 @@ def upsert_node(node_id, n):
"""
ndict = _node_to_dict(n)
_post_json("/api/nodes", {node_id: ndict})
_queue_post_json("/api/nodes", {node_id: ndict}, priority=_NODE_POST_PRIORITY)
if DEBUG:
user = _get(ndict, "user") or {}
@@ -286,7 +344,7 @@ def store_packet_dict(p: dict):
"rssi": int(rssi) if rssi is not None else None,
"hop_limit": int(hop) if hop is not None else None,
}
_post_json("/api/messages", msg)
_queue_post_json("/api/messages", msg, priority=_MESSAGE_POST_PRIORITY)
if DEBUG:
print(