mirror of
https://github.com/zvx-echo6/meshai.git
synced 2026-05-21 15:14:45 +02:00
fix: ACK-accelerated delivery — immediate on ACK, retry once, abort on double fail
Delays 1.5-2.5s (was 3-5s, only for broadcasts now). DMs: send → ACK → next immediately. No ACK → retry once → abort. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
736d6a313a
commit
34f894ea79
2 changed files with 95 additions and 87 deletions
|
|
@ -35,8 +35,8 @@ class ConnectionConfig:
|
|||
class ResponseConfig:
|
||||
"""Response behavior settings."""
|
||||
|
||||
delay_min: float = 3.0
|
||||
delay_max: float = 5.0
|
||||
delay_min: float = 1.5
|
||||
delay_max: float = 2.5
|
||||
max_length: int = 200
|
||||
max_messages: int = 3
|
||||
|
||||
|
|
|
|||
|
|
@ -24,10 +24,11 @@ class Responder:
|
|||
destination: Optional[str] = None,
|
||||
channel: int = 0,
|
||||
) -> bool:
|
||||
"""Send response messages with ACK waiting and retry.
|
||||
"""Send response messages with ACK-accelerated delivery.
|
||||
|
||||
For DMs: waits for ACK before sending next message, retries once on failure.
|
||||
For broadcasts: uses delay-based pacing (no ACK for broadcasts).
|
||||
DMs: Send -> wait for ACK -> if ACK, send next immediately.
|
||||
If no ACK, retry once -> if still no ACK, abort.
|
||||
Broadcasts: delay-based pacing (no ACK available).
|
||||
"""
|
||||
if isinstance(messages, str):
|
||||
messages = [messages]
|
||||
|
|
@ -39,36 +40,44 @@ class Responder:
|
|||
is_dm = destination is not None
|
||||
|
||||
for i, msg in enumerate(messages):
|
||||
# Randomized delay before sending (except first message)
|
||||
if i > 0:
|
||||
delay = random.uniform(self.config.delay_min, self.config.delay_max)
|
||||
await asyncio.sleep(delay)
|
||||
|
||||
if is_dm and hasattr(self.connector, 'send_and_wait_ack'):
|
||||
# DMs: send and wait for ACK
|
||||
# Send and wait for ACK
|
||||
ack = await asyncio.get_event_loop().run_in_executor(
|
||||
None,
|
||||
self.connector.send_and_wait_ack,
|
||||
msg, destination, channel, 30.0,
|
||||
)
|
||||
|
||||
if not ack:
|
||||
# Retry once
|
||||
logger.warning(f"No ACK for msg {i+1}/{len(messages)}, retrying...")
|
||||
await asyncio.sleep(random.uniform(3.0, 5.0))
|
||||
ack = await asyncio.get_event_loop().run_in_executor(
|
||||
None,
|
||||
self.connector.send_and_wait_ack,
|
||||
msg, destination, channel, 30.0,
|
||||
)
|
||||
if not ack:
|
||||
logger.error(f"No ACK after retry for msg {i+1}/{len(messages)}, skipping remaining")
|
||||
success = False
|
||||
break
|
||||
if ack:
|
||||
# ACK received - next message sends immediately (no delay)
|
||||
logger.debug(f"ACK msg {i+1}/{len(messages)}: {msg[:50]}...")
|
||||
continue
|
||||
|
||||
# No ACK - retry same message once after short pause
|
||||
logger.warning(f"No ACK for msg {i+1}/{len(messages)}, retrying...")
|
||||
await asyncio.sleep(2.0)
|
||||
|
||||
ack = await asyncio.get_event_loop().run_in_executor(
|
||||
None,
|
||||
self.connector.send_and_wait_ack,
|
||||
msg, destination, channel, 30.0,
|
||||
)
|
||||
|
||||
if ack:
|
||||
logger.debug(f"ACK on retry msg {i+1}/{len(messages)}")
|
||||
continue
|
||||
|
||||
# Double failure - abort
|
||||
logger.error(f"No ACK after retry msg {i+1}/{len(messages)}, aborting remaining")
|
||||
success = False
|
||||
break
|
||||
|
||||
logger.debug(f"Sent+ACK msg {i+1}/{len(messages)}: {msg[:50]}...")
|
||||
else:
|
||||
# Broadcasts or fallback: fire and delay
|
||||
# Broadcasts or fallback: delay-based pacing
|
||||
if i > 0:
|
||||
delay = random.uniform(self.config.delay_min, self.config.delay_max)
|
||||
await asyncio.sleep(delay)
|
||||
|
||||
sent = self.connector.send_message(
|
||||
text=msg,
|
||||
destination=destination,
|
||||
|
|
@ -82,4 +91,3 @@ class Responder:
|
|||
logger.debug(f"Sent msg {i+1}/{len(messages)}: {msg[:50]}...")
|
||||
|
||||
return success
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue