Merge pull request #183 from fmoessbauer/fm/darc-mowas-more-reliable

Improve retransmissions on DARC MoWaS bridge
This commit is contained in:
Adam Gessaman authored and GitHub committed 2026-05-16 08:33:42 -07:00
commit e7534c2a0b
2 files changed
+14 -3

No files matched your search

+6 -1
View File
@@ -5,6 +5,7 @@ Handles all bot commands, keyword matching, and response generation
"""
import asyncio
from datetime import datetime
import random
import time
from dataclasses import dataclass
@@ -1061,6 +1062,7 @@ class CommandManager:
skip_user_rate_limit: bool = False,
rate_limit_key: str | None = None,
scope: str | None = None,
timestamp: datetime | None = None,
) -> bool:
"""Send a channel message using meshcore_py (optional flood scope).
@@ -1133,7 +1135,10 @@ class CommandManager:
_max_retries = 2
for _attempt in range(_max_retries + 1):
try:
result = await self.bot.meshcore.commands.send_chan_msg(channel_num, content)
result = await self.bot.meshcore.commands.send_chan_msg(
channel_num, content,
timestamp=int(timestamp.timestamp()) if timestamp else None,
)
finally:
if not scope_is_global and hasattr(self.bot.meshcore.commands, "set_flood_scope"):
await self.bot.meshcore.commands.set_flood_scope("*")
@@ -19,7 +19,7 @@ import time
import xml.dom.minidom
from asyncio import AbstractEventLoop
from dataclasses import dataclass
from datetime import datetime
from datetime import datetime, timedelta
from typing import Any, cast
import aiohttp
@@ -176,11 +176,14 @@ class DARC_MoWaS_Service(BaseServicePlugin):
Send all chunks, each with async retry if configured.
Note, that we cannot guarantee that the messages arrive in-order,
but as the chunks have a (x/n) identifier at the end, the user still
should be able to grasp the message correctly.
should be able to grasp the message correctly. We further add
an ascending timestamp to each message (also used on re-transmission) to
let the client restore the order, as well as deduplicate retransmissions.
Ideally this chunking should be implemented at protocol level to
guarantee the atomicity and order of the full message.
"""
ts_now = datetime.now()
for i, chunk in enumerate(chunks):
asyncio.create_task(
self._send_chunk_with_retry(
@@ -188,6 +191,7 @@ class DARC_MoWaS_Service(BaseServicePlugin):
chunk,
i,
len(chunks),
ts_now + timedelta(seconds=1)
)
)
@@ -197,6 +201,7 @@ class DARC_MoWaS_Service(BaseServicePlugin):
chunk: str,
index: int,
total: int,
timestamp: datetime,
) -> None:
"""Send a chunk and retry until acked or retries exhausted."""
tracker = getattr(self.bot, "transmission_tracker", None)
@@ -210,6 +215,7 @@ class DARC_MoWaS_Service(BaseServicePlugin):
chunk,
command_id=cmd_id,
skip_user_rate_limit=True,
timestamp=timestamp
):
self.logger.warning("Send failed for '%s'", channel)
return