Skip to content

Commit

Permalink
fix(plugin): fix retry logic
Browse files Browse the repository at this point in the history
Link: #51
Signed-off-by: Vincenzo Palazzo <[email protected]>
  • Loading branch information
vincenzopalazzo committed Feb 7, 2024
1 parent e722987 commit 04b75da
Show file tree
Hide file tree
Showing 4 changed files with 204 additions and 7 deletions.
134 changes: 134 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions folgore-plugin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ folgore-esplora = { path = "../folgore-esplora" }
folgore-bitcoind = { path = "../folgore-bitcoind" }
serde = "1.0.159"
serde_json = "1.0.95"

[dev-dependencies]
env_logger = "0.11.1"
13 changes: 13 additions & 0 deletions folgore-plugin/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,16 @@ fn main() {
let plugin = plugin::build_plugin();
plugin.start();
}

#[cfg(test)]
use std::sync::Once;

#[cfg(test)]
static INIT: Once = Once::new();

#[cfg(test)]
fn configure_tests() {
INIT.call_once(|| {
env_logger::init();
});
}
61 changes: 54 additions & 7 deletions folgore-plugin/src/recovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ use folgore_common::Result;
/// Esplora implement something similar, and we work around
/// with this strategy.
pub struct TimeoutRetry {
pub timeout: RefCell<Duration>,
pub times: RefCell<u8>,
pub(crate) timeout: RefCell<Duration>,
pub(crate) retry_state: RefCell<u8>,
pub(crate) times: u8,
}

// SAFETY: All the backend request and blocking
Expand All @@ -34,7 +35,8 @@ impl TimeoutRetry {
pub fn new(duration: Option<Duration>) -> Self {
Self {
timeout: RefCell::new(duration.unwrap_or(Duration::from_secs(60))),
times: RefCell::new(4),
retry_state: RefCell::new(0),
times: 4,
}
}
}
Expand All @@ -54,13 +56,13 @@ impl RecoveryStrategy for TimeoutRetry {
while result.is_err() {
log::info!(
"running into retry logic due a request failing. Time `{}` waiting `{}` secs",
*self.times.borrow(),
self.times,
self.timeout.borrow().as_secs()
);
if self.times.borrow().eq(&4) {
if self.retry_state.borrow().eq(&self.times) {
log::info!(
"we try {} times the request but the error persist",
self.times.borrow()
*self.retry_state.borrow()
);
log::debug!(
"Error during the recovery strategy: `{:?}`",
Expand All @@ -79,9 +81,54 @@ impl RecoveryStrategy for TimeoutRetry {
log::info!("Waiting timeout end");
// now we increase the timeout
self.timeout.borrow_mut().mul_assign(2);
self.times.borrow_mut().add_assign(1);
self.retry_state.borrow_mut().add_assign(1);
result = cb();
}
result
}
}

#[cfg(test)]
mod tests {
use std::time::Duration;

use folgore_common::prelude::cln_plugin::error;
use folgore_common::prelude::cln_plugin::errors::PluginError;

use super::{RecoveryStrategy, TimeoutRetry};

use crate::configure_tests;

#[test]
fn test_simple_retry() {
configure_tests();
let strategy = TimeoutRetry::new(Some(Duration::from_millis(10)));

let err: Result<(), PluginError> = strategy.apply(|| Err(error!("")));
assert!(err.is_err());
}

#[test]
fn test_state_strategy_one() {
configure_tests();
let strategy = TimeoutRetry::new(Some(Duration::from_millis(10)));

let _: Result<(), PluginError> = strategy.apply(|| Err(error!("")));
assert_eq!(*strategy.retry_state.borrow(), 4);
let mut time = 10;
for _ in 0..4 {
time = time * 2;
}
assert_eq!(*strategy.timeout.borrow(), Duration::from_millis(time));
}

#[test]
fn test_state_strategy_two() {
configure_tests();
let strategy = TimeoutRetry::new(Some(Duration::from_millis(10)));

let _: Result<(), PluginError> = strategy.apply(|| Ok(()));
assert_eq!(*strategy.retry_state.borrow(), 0);
assert_eq!(*strategy.timeout.borrow(), Duration::from_millis(10));
}
}

0 comments on commit 04b75da

Please sign in to comment.