core: quiet transport reconnect spam for LAN-only / dead-server mode
SSE and RTC logged an error (and SSE flipped status) on every reconnect attempt, so running without a reachable server — the legit LAN-only case — flooded the log and spammed on_status(false). Now each transport reports a drop once per outage streak and resets on reconnect; SSE no longer logs per-send failures (implied by the connection-state line). Verified: serverless agent↔peer LAN sync still works both directions, with the agent log down from ~25 lines to 7 (one disconnect notice per transport, then real activity). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+15
-8
@@ -217,12 +217,21 @@ impl Transport for SseTransport {
|
|||||||
let min = Duration::from_millis(500);
|
let min = Duration::from_millis(500);
|
||||||
let max = Duration::from_secs(10);
|
let max = Duration::from_secs(10);
|
||||||
let mut backoff = min;
|
let mut backoff = min;
|
||||||
|
// Report a drop / log an error only once per outage streak — a dead
|
||||||
|
// or absent server (LAN-only mode) must not spam every retry.
|
||||||
|
let mut down_reported = false;
|
||||||
while running.load(Ordering::SeqCst) {
|
while running.load(Ordering::SeqCst) {
|
||||||
match this.stream_once(&running, &sink, &status).await {
|
match this.stream_once(&running, &sink, &status).await {
|
||||||
Ok(()) => backoff = min, // clean EOF — reconnect promptly
|
Ok(()) => {
|
||||||
|
backoff = min; // clean EOF — reconnect promptly
|
||||||
|
down_reported = false;
|
||||||
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
status(false);
|
if !down_reported {
|
||||||
eprintln!("tethercore[{}]: {e}", this.name());
|
status(false);
|
||||||
|
eprintln!("tethercore[{}]: {e}", this.name());
|
||||||
|
down_reported = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if running.load(Ordering::SeqCst) {
|
if running.load(Ordering::SeqCst) {
|
||||||
@@ -230,18 +239,16 @@ impl Transport for SseTransport {
|
|||||||
backoff = (backoff * 2).min(max);
|
backoff = (backoff * 2).min(max);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
status(false);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn publish(&self, rt: &Handle, msg: Message) {
|
fn publish(&self, rt: &Handle, msg: Message) {
|
||||||
let http = self.http.clone();
|
let http = self.http.clone();
|
||||||
let cfg = self.cfg.clone();
|
let cfg = self.cfg.clone();
|
||||||
let name = self.name();
|
|
||||||
rt.spawn(async move {
|
rt.spawn(async move {
|
||||||
if let Err(e) = post(&http, &cfg, &msg.text).await {
|
// A failed send is already implied by the connection-state log;
|
||||||
eprintln!("tethercore[{name}]: send failed: {e}");
|
// don't log per-send (every clipboard change would spam offline).
|
||||||
}
|
let _ = post(&http, &cfg, &msg.text).await;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-2
@@ -419,10 +419,21 @@ impl Transport for RtcTransport {
|
|||||||
let min = Duration::from_millis(500);
|
let min = Duration::from_millis(500);
|
||||||
let max = Duration::from_secs(10);
|
let max = Duration::from_secs(10);
|
||||||
let mut backoff = min;
|
let mut backoff = min;
|
||||||
|
// Log a signaling error only once per outage streak (LAN-only / dead
|
||||||
|
// server must not spam).
|
||||||
|
let mut logged = false;
|
||||||
while running.load(Ordering::SeqCst) {
|
while running.load(Ordering::SeqCst) {
|
||||||
match self.signal_stream(&running).await {
|
match self.signal_stream(&running).await {
|
||||||
Ok(()) => backoff = min,
|
Ok(()) => {
|
||||||
Err(e) => eprintln!("tethercore[rtc]: {e}"),
|
backoff = min;
|
||||||
|
logged = false;
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
if !logged {
|
||||||
|
eprintln!("tethercore[rtc]: {e}");
|
||||||
|
logged = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if running.load(Ordering::SeqCst) {
|
if running.load(Ordering::SeqCst) {
|
||||||
tokio::time::sleep(backoff).await;
|
tokio::time::sleep(backoff).await;
|
||||||
|
|||||||
Reference in New Issue
Block a user