small optimizations, add comments

This commit is contained in:
pstruebi
2025-10-01 15:19:20 +02:00
parent b922eca39c
commit 653de2da6a
4 changed files with 66 additions and 22 deletions

View File

@@ -75,6 +75,8 @@ stty -F /dev/ttyAMA3 -a | grep -o 'hupcl' || echo "-hupcl is set"
# Audio latency
if there is hearable audio error with aes67, tune sess.latency.msec in pipewire-aes67.conf
if latency is piling up something may be blocking the event loop in multicast_server.py - the event loop must never block at any time
---
After completing these steps, your device will be discoverable as `<hostname>.<domain>` (e.g., `box1.auracast.local`) on the local network via mDNS.

View File

@@ -1 +1 @@
5078804E6FBCF893D5537715FD928E46AD576ECA
5078804E6FBCF893D5537715FD928E46AD576ECB

View File

@@ -1,4 +1,7 @@
import glob
""" the main server where our multicaster objects live.
TODO: in the future the multicaster objects should run in their own threads or even make a second server since everything thats blocking the main event loop leads to inceased latency.
"""
import os
import logging as log
import uuid
@@ -39,6 +42,9 @@ pcs: Set[RTCPeerConnection] = set() # keep refs so they dont GC early
os.environ["PULSE_LATENCY_MSEC"] = "3"
# In-memory cache to avoid disk I/O on hot paths like /status
SETTINGS_CACHE: dict = {}
class Offer(BaseModel):
sdp: str
type: str
@@ -58,21 +64,37 @@ def get_device_index_by_name(name: str):
return None
def load_stream_settings() -> dict:
"""Load persisted stream settings if available."""
if os.path.exists(STREAM_SETTINGS_FILE):
try:
def _hydrate_settings_cache_from_disk() -> None:
"""Populate SETTINGS_CACHE once from disk at startup.
Safe to call multiple times; errors fall back to empty dict.
"""
global SETTINGS_CACHE
try:
if os.path.exists(STREAM_SETTINGS_FILE):
with open(STREAM_SETTINGS_FILE, 'r', encoding='utf-8') as f:
return json.load(f)
except Exception:
return {}
return {}
SETTINGS_CACHE = json.load(f)
else:
SETTINGS_CACHE = {}
except Exception:
SETTINGS_CACHE = {}
def load_stream_settings() -> dict:
"""Return stream settings from in-memory cache.
The cache is hydrated once at startup and updated by save_stream_settings().
No disk I/O occurs here.
"""
global SETTINGS_CACHE
return SETTINGS_CACHE
def save_stream_settings(settings: dict):
"""Save stream settings to disk."""
"""Update in-memory settings cache and persist to disk."""
global SETTINGS_CACHE
SETTINGS_CACHE = dict(settings)
try:
with open(STREAM_SETTINGS_FILE, 'w', encoding='utf-8') as f:
json.dump(settings, f, indent=2)
json.dump(SETTINGS_CACHE, f, indent=2)
except Exception as e:
log.error('Unable to persist stream settings: %s', e)
@@ -276,13 +298,6 @@ async def get_status():
return status
@app.get("/long_block")
async def long_block():
"""Test endpoint that simulates a small delay without blocking the event loop."""
time.sleep(0.3)
return True
async def _autostart_from_settings():
"""Background task: auto-start last selected device-based input at server startup.
@@ -291,7 +306,6 @@ async def _autostart_from_settings():
and initializes streaming.
"""
try:
settings = load_stream_settings() or {}
audio_mode = settings.get('audio_mode')
input_device_name = settings.get('input_device')
@@ -361,17 +375,19 @@ async def _autostart_from_settings():
bigs=bigs,
)
# Initialize and start
await asyncio.sleep(0.5)
await initialize(conf)
return
await asyncio.sleep(2)
except Exception:
log.warning("Autostart task failed", exc_info=True)
#TODO: enable and test this
@app.on_event("startup")
async def _startup_autostart_event():
# Spawn the autostart task without blocking startup
log.info("Refreshing PipeWire device cache.")
# Hydrate settings cache once to avoid disk I/O during /status
_hydrate_settings_cache_from_disk()
refresh_pw_cache()
asyncio.create_task(_autostart_from_settings())
@@ -619,4 +635,4 @@ if __name__ == '__main__':
format='%(module)s.py:%(lineno)d %(levelname)s: %(message)s'
)
# Bind to localhost only for security: prevents network access, only frontend on same machine can connect
uvicorn.run(app, host="127.0.0.1", port=5000)
uvicorn.run(app, host="127.0.0.1", port=5000, access_log=False)

26
src/scripts/hit_status.sh Normal file
View File

@@ -0,0 +1,26 @@
#!/usr/bin/env bash
# Usage: ./hit_status.sh [COUNT] [SLEEP_SECONDS]
# Always targets http://127.0.0.1:5000/status
# Defaults: COUNT=100 SLEEP_SECONDS=0
# Example: ./hit_status.sh 100 0.05
set -euo pipefail
URL="http://127.0.0.1:5000/status"
COUNT="${1:-100}"
SLEEP_SECS="${2:-0}"
# Ensure COUNT is an integer
if ! [[ "$COUNT" =~ ^[0-9]+$ ]]; then
echo "COUNT must be an integer, got: $COUNT" >&2
exit 1
fi
for i in $(seq 1 "$COUNT"); do
echo "[$i/$COUNT] GET $URL"
curl -sS "$URL" > /dev/null || echo "Request $i failed"
# Sleep if non-zero (supports floats, no bc needed)
if [[ "$SLEEP_SECS" != "0" && "$SLEEP_SECS" != "0.0" && "$SLEEP_SECS" != "" ]]; then
sleep "$SLEEP_SECS"
fi
done