feat: implement notification system and backoff strategy for rTorrent polling
This commit is contained in:
@@ -85,10 +85,24 @@ pub async fn add_torrent_handler(
|
||||
tracing::error!("rTorrent returned fault: {}", response);
|
||||
return StatusCode::INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
let _ =
|
||||
state
|
||||
.event_bus
|
||||
.send(shared::AppEvent::Notification(shared::SystemNotification {
|
||||
level: shared::NotificationLevel::Success,
|
||||
message: "Torrent added successfully".to_string(),
|
||||
}));
|
||||
StatusCode::OK
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Failed to add torrent: {}", e);
|
||||
let _ =
|
||||
state
|
||||
.event_bus
|
||||
.send(shared::AppEvent::Notification(shared::SystemNotification {
|
||||
level: shared::NotificationLevel::Error,
|
||||
message: format!("Failed to add torrent: {}", e),
|
||||
}));
|
||||
StatusCode::INTERNAL_SERVER_ERROR
|
||||
}
|
||||
}
|
||||
@@ -121,7 +135,15 @@ pub async fn handle_torrent_action(
|
||||
// Special handling for delete_with_data
|
||||
if payload.action == "delete_with_data" {
|
||||
return match delete_torrent_with_data(&client, &payload.hash).await {
|
||||
Ok(msg) => (StatusCode::OK, msg).into_response(),
|
||||
Ok(msg) => {
|
||||
let _ = state.event_bus.send(shared::AppEvent::Notification(
|
||||
shared::SystemNotification {
|
||||
level: shared::NotificationLevel::Success,
|
||||
message: format!("Torrent deleted with data: {}", payload.hash),
|
||||
},
|
||||
));
|
||||
(StatusCode::OK, msg).into_response()
|
||||
}
|
||||
Err((status, msg)) => (status, msg).into_response(),
|
||||
};
|
||||
}
|
||||
@@ -136,7 +158,16 @@ pub async fn handle_torrent_action(
|
||||
let params = vec![RpcParam::from(payload.hash.as_str())];
|
||||
|
||||
match client.call(method, ¶ms).await {
|
||||
Ok(_) => (StatusCode::OK, "Action executed").into_response(),
|
||||
Ok(_) => {
|
||||
let _ =
|
||||
state
|
||||
.event_bus
|
||||
.send(shared::AppEvent::Notification(shared::SystemNotification {
|
||||
level: shared::NotificationLevel::Info,
|
||||
message: format!("Action '{}' executed on torrent", payload.action),
|
||||
}));
|
||||
(StatusCode::OK, "Action executed").into_response()
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("RPC error: {}", e);
|
||||
(
|
||||
|
||||
@@ -147,6 +147,8 @@ async fn main() {
|
||||
tokio::spawn(async move {
|
||||
let client = xmlrpc::RtorrentClient::new(&socket_path);
|
||||
let mut previous_torrents: Vec<Torrent> = Vec::new();
|
||||
let mut consecutive_errors = 0;
|
||||
let mut backoff_duration = Duration::from_secs(1);
|
||||
|
||||
loop {
|
||||
// 1. Fetch Torrents
|
||||
@@ -158,6 +160,21 @@ async fn main() {
|
||||
// Handle Torrents
|
||||
match torrents_result {
|
||||
Ok(new_torrents) => {
|
||||
// Check if we recovered from an error state
|
||||
if consecutive_errors > 0 {
|
||||
tracing::info!(
|
||||
"Reconnected to rTorrent after {} failures.",
|
||||
consecutive_errors
|
||||
);
|
||||
let _ =
|
||||
event_bus_tx.send(AppEvent::Notification(shared::SystemNotification {
|
||||
level: shared::NotificationLevel::Success,
|
||||
message: "Reconnected to rTorrent".to_string(),
|
||||
}));
|
||||
consecutive_errors = 0;
|
||||
backoff_duration = Duration::from_secs(1);
|
||||
}
|
||||
|
||||
// Update latest state
|
||||
let _ = tx_clone.send(new_torrents.clone());
|
||||
|
||||
@@ -186,6 +203,23 @@ async fn main() {
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!("Error fetching torrents in background: {}", e);
|
||||
consecutive_errors += 1;
|
||||
|
||||
// If this is the first error after success (or startup), notify clients
|
||||
if consecutive_errors == 1 {
|
||||
let _ =
|
||||
event_bus_tx.send(AppEvent::Notification(shared::SystemNotification {
|
||||
level: shared::NotificationLevel::Error,
|
||||
message: format!("Lost connection to rTorrent: {}", e),
|
||||
}));
|
||||
}
|
||||
|
||||
// Exponential backoff with a cap of 30 seconds
|
||||
backoff_duration = std::cmp::min(backoff_duration * 2, Duration::from_secs(30));
|
||||
tracing::warn!(
|
||||
"Backoff: Sleeping for {:?} due to rTorrent error.",
|
||||
backoff_duration
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,7 +233,7 @@ async fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
tokio::time::sleep(Duration::from_secs(1)).await;
|
||||
tokio::time::sleep(backoff_duration).await;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user