fix: improve presence reconnection logic and error handling

Co-authored-by: Copilot <[email protected]>
This commit is contained in:
HorizonCodeandCopilot committed 2026-04-26 14:04:06 +02:00
1 parent 7e40536ec8
commit ef36f49a6f
1 file changed
+30 -8
+30 -8
View File
@@ -1,6 +1,6 @@
use discord_rich_presence::{
activity::{Activity, Assets, Button, Timestamps},
DiscordIpc, DiscordIpcClient,
activity::{Activity, Assets, Button, Timestamps},
};
use once_cell::sync::Lazy;
use std::future::Future;
@@ -91,7 +91,10 @@ impl PresenceActor {
}
}
fn handle_connect(&mut self, responder: oneshot::Sender<bool>) -> Pin<Box<dyn Future<Output = ()> + Send + '_>> {
fn handle_connect(
&mut self,
responder: oneshot::Sender<bool>,
) -> Pin<Box<dyn Future<Output = ()> + Send + '_>> {
Box::pin(async move {
if self.client.is_some() {
let _ = responder.send(true);
@@ -108,12 +111,26 @@ impl PresenceActor {
let _ = responder.send(true);
}
Err(e) => {
eprintln!("Failed to connect to Discord: {:?}. Retrying in 5s...", e);
eprintln!(
"Failed to connect to Discord: {:?}. Scheduling bounded retry...",
e
);
let tx = PRESENCE_TX.clone();
tokio::spawn(async move {
tokio::time::sleep(Duration::from_secs(5)).await;
let (resp_tx, _) = oneshot::channel();
let _ = tx.send(PresenceCommand::Connect(resp_tx)).await;
for attempt in 1..=3 {
tokio::time::sleep(Duration::from_secs(5 * attempt)).await;
let (resp_tx, rx) = oneshot::channel();
if tx.send(PresenceCommand::Connect(resp_tx)).await.is_ok() {
if rx.await.unwrap_or(false) {
println!("Actor: Reconnection attempt {} succeeded", attempt);
break;
}
println!(
"Actor: Reconnection attempt {} failed, retrying...",
attempt
);
}
}
});
if !responder.is_closed() {
@@ -164,8 +181,13 @@ impl PresenceActor {
eprintln!("Failed to set activity, disconnecting: {:?}", e);
self.client = None;
let (tx, _) = oneshot::channel();
self.handle_connect(tx).await;
// Don't await reconnection here - send command to avoid blocking the actor
let tx = PRESENCE_TX.clone();
tokio::spawn(async move {
tokio::time::sleep(Duration::from_secs(1)).await;
let (resp_tx, _) = oneshot::channel();
let _ = tx.send(PresenceCommand::Connect(resp_tx)).await;
});
} else {
println!("Actor: Presence updated successfully.");
}