Drop frequency of contact sync task, make standard polling opt-in only

This commit is contained in:
Jack Kingsman
2026-03-10 14:04:51 -07:00
parent eaee66f836
commit 97997e23e8
22 changed files with 571 additions and 93 deletions
+8
View File
@@ -137,15 +137,20 @@ async def send_direct_message_to_contact(
) -> Any:
"""Send a direct message and persist/broadcast the outgoing row."""
contact_data = contact.to_radio_dict()
contact_ensured_on_radio = False
async with radio_manager.radio_operation("send_direct_message") as mc:
logger.debug("Ensuring contact %s is on radio before sending", contact.public_key[:12])
add_result = await mc.commands.add_contact(contact_data)
if add_result.type == EventType.ERROR:
logger.warning("Failed to add contact to radio: %s", add_result.payload)
else:
contact_ensured_on_radio = True
cached_contact = mc.get_contact_by_key_prefix(contact.public_key[:12])
if not cached_contact:
cached_contact = contact_data
else:
contact_ensured_on_radio = True
logger.info("Sending direct message to %s", contact.public_key[:12])
now = int(now_fn())
@@ -158,6 +163,9 @@ async def send_direct_message_to_contact(
if result.type == EventType.ERROR:
raise HTTPException(status_code=500, detail=f"Failed to send message: {result.payload}")
if contact_ensured_on_radio and not contact.on_radio:
await contact_repository.set_on_radio(contact.public_key.lower(), True)
message = await create_outgoing_direct_message(
conversation_key=contact.public_key.lower(),
text=text,
+45 -5
View File
@@ -1,8 +1,13 @@
import asyncio
import logging
from app.config import settings
logger = logging.getLogger(__name__)
POST_CONNECT_SETUP_TIMEOUT_SECONDS = 300
POST_CONNECT_SETUP_MAX_ATTEMPTS = 2
async def run_post_connect_setup(radio_manager) -> None:
"""Run shared radio initialization after a transport connection succeeds."""
@@ -24,7 +29,7 @@ async def run_post_connect_setup(radio_manager) -> None:
if radio_manager._setup_lock is None:
radio_manager._setup_lock = asyncio.Lock()
async with radio_manager._setup_lock:
async def _setup_body() -> None:
if not radio_manager.meshcore:
return
radio_manager._setup_in_progress = True
@@ -132,20 +137,51 @@ async def run_post_connect_setup(radio_manager) -> None:
# These tasks acquire their own locks when they need radio access.
start_periodic_sync()
start_periodic_advert()
start_message_polling()
if settings.enable_message_poll_fallback:
start_message_polling()
else:
logger.info("Fallback message polling disabled; relying on radio events")
radio_manager._setup_complete = True
finally:
radio_manager._setup_in_progress = False
async with radio_manager._setup_lock:
await asyncio.wait_for(_setup_body(), timeout=POST_CONNECT_SETUP_TIMEOUT_SECONDS)
logger.info("Post-connect setup complete")
async def prepare_connected_radio(radio_manager, *, broadcast_on_success: bool = True) -> None:
"""Finish setup for an already-connected radio and optionally broadcast health."""
from app.websocket import broadcast_health
from app.websocket import broadcast_error, broadcast_health
for attempt in range(1, POST_CONNECT_SETUP_MAX_ATTEMPTS + 1):
try:
await radio_manager.post_connect_setup()
break
except asyncio.TimeoutError as exc:
if attempt < POST_CONNECT_SETUP_MAX_ATTEMPTS:
logger.warning(
"Post-connect setup timed out after %ds on attempt %d/%d; retrying once",
POST_CONNECT_SETUP_TIMEOUT_SECONDS,
attempt,
POST_CONNECT_SETUP_MAX_ATTEMPTS,
)
continue
logger.error(
"Post-connect setup timed out after %ds on %d attempts. Initial radio offload "
"took too long; something is probably wrong.",
POST_CONNECT_SETUP_TIMEOUT_SECONDS,
POST_CONNECT_SETUP_MAX_ATTEMPTS,
)
broadcast_error(
"Radio startup appears stuck",
"Initial radio offload took too long. Reboot the radio and restart the server.",
)
raise RuntimeError("Post-connect setup timed out") from exc
await radio_manager.post_connect_setup()
radio_manager._last_connected = True
if broadcast_on_success:
broadcast_health(True, radio_manager.connection_info)
@@ -197,7 +233,11 @@ async def connection_monitor_loop(radio_manager) -> None:
await prepare_connected_radio(radio_manager, broadcast_on_success=True)
consecutive_setup_failures = 0
elif current_connected and not radio_manager.is_setup_complete:
elif (
current_connected
and not radio_manager.is_setup_complete
and not radio_manager.is_setup_in_progress
):
logger.info("Retrying post-connect setup...")
await prepare_connected_radio(radio_manager, broadcast_on_success=True)
consecutive_setup_failures = 0