diff --git a/benches/app.rs b/benches/app.rs index f81bdf2..d1b057c 100644 --- a/benches/app.rs +++ b/benches/app.rs @@ -5,7 +5,7 @@ use gurk::app::App; use gurk::config::{Config, User}; use gurk::signal::test::SignalManagerMock; use gurk::storage::{ForgetfulStorage, MemCache}; -use presage::prelude::Content; +use presage::libsignal_service::content::Content; use tracing::info; fn test_app() -> App { diff --git a/src/backoff.rs b/src/backoff.rs new file mode 100644 index 0000000..d95af55 --- /dev/null +++ b/src/backoff.rs @@ -0,0 +1,36 @@ +use std::time::Duration; + +const FIBONACCI_TIMEOUTS: [Duration; 9] = [ + Duration::from_secs(1), + Duration::from_secs(2), + Duration::from_secs(3), + Duration::from_secs(5), + Duration::from_secs(8), + Duration::from_secs(13), + Duration::from_secs(21), + Duration::from_secs(34), + Duration::from_secs(55), +]; + +#[derive(Debug, Default)] +pub struct Backoff { + count: usize, +} + +impl Backoff { + pub fn new() -> Self { + Default::default() + } + + pub fn get(&mut self) -> Duration { + let timeout = FIBONACCI_TIMEOUTS[self.count]; + if self.count + 1 < FIBONACCI_TIMEOUTS.len() { + self.count += 1; + } + timeout + } + + pub fn reset(&mut self) { + self.count = 0; + } +} diff --git a/src/lib.rs b/src/lib.rs index 5ed90b2..203ef96 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,7 @@ //! Signal Messenger client for terminal pub mod app; +pub mod backoff; mod channels; pub mod config; pub mod cursor; diff --git a/src/main.rs b/src/main.rs index aba0afb..a3335b9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,6 +16,7 @@ use crossterm::{ terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, }; use gurk::app::App; +use gurk::backoff::Backoff; use gurk::storage::{sync_from_signal, JsonStorage, MemCache, SqliteStorage, Storage}; use gurk::{config, signal, ui}; use presage::libsignal_service::content::Content; @@ -155,6 +156,7 @@ async fn run_single_threaded(relink: bool) -> anyhow::Result<()> { let inner_tx = tx.clone(); tokio::task::spawn_local(async move { + let mut backoff = Backoff::new(); loop { let mut messages = if !is_online().await { tokio::time::sleep(std::time::Duration::from_secs(10)).await; @@ -195,12 +197,16 @@ async fn run_single_threaded(relink: bool) -> anyhow::Result<()> { } while let Some(message) = messages.next().await { + backoff.reset(); inner_tx .send(Event::Message(message)) .await .expect("logic error: events channel closed") } - error!("messages channel disconnected. trying to reconnect.") + + let after = backoff.get(); + error!(?after, "messages channel disconnected. trying to reconnect"); + tokio::time::sleep(after).await; } });