jup_sdk/retry.rs
1/// Client-side retry module.
2/// Provides intelligent retry, error classification, and recovery strategies.
3use crate::types::JupiterError;
4use std::time::Duration;
5use tokio::time;
6
7/// Configuration for retry behavior.
8#[derive(Debug, Clone)]
9pub struct RetryConfig {
10 pub max_retries: u32,
11 pub initial_delay: Duration,
12 pub max_delay: Duration,
13 pub backoff_multiplier: f64,
14}
15
16impl Default for RetryConfig {
17 fn default() -> Self {
18 Self {
19 max_retries: 3,
20 initial_delay: Duration::from_millis(500),
21 max_delay: Duration::from_secs(5),
22 backoff_multiplier: 2.0,
23 }
24 }
25}
26
27/// Trait defining retry strategy behavior.
28pub trait RetryStrategy {
29 /// Determines if a retry should be attempted based on the error and attempt count.
30 ///
31 /// # Params
32 /// error - The error that occurred
33 /// attempt - The current attempt number (1-based)
34 ///
35 /// # Example
36 /// ```
37 /// # use crate::JupiterError;
38 /// # struct MyStrategy;
39 /// # impl RetryStrategy for MyStrategy {
40 /// # fn should_retry(&self, error: &JupiterError, attempt: u32) -> bool {
41 /// # attempt < 3 && !error.is_fatal()
42 /// # }
43 /// # fn get_delay(&self, attempt: u32) -> Duration {
44 /// # Duration::from_millis(100 * attempt as u64)
45 /// # }
46 /// # }
47 /// let strategy = MyStrategy;
48 /// let error = JupiterError::NetworkError;
49 /// assert!(strategy.should_retry(&error, 1));
50 /// ```
51 fn should_retry(&self, error: &JupiterError, attempt: u32) -> bool;
52
53 /// Calculates the delay before the next retry attempt.
54 ///
55 /// # Params
56 /// attempt - The current attempt number (1-based)
57 ///
58 /// # Example
59 /// ```
60 /// # use std::time::Duration;
61 /// # struct MyStrategy;
62 /// # impl RetryStrategy for MyStrategy {
63 /// # fn should_retry(&self, _error: &JupiterError, _attempt: u32) -> bool { true }
64 /// # fn get_delay(&self, attempt: u32) -> Duration {
65 /// # Duration::from_millis(100 * attempt as u64)
66 /// # }
67 /// # }
68 /// let strategy = MyStrategy;
69 /// assert_eq!(strategy.get_delay(1), Duration::from_millis(100));
70 /// assert_eq!(strategy.get_delay(2), Duration::from_millis(200));
71 /// ```
72 fn get_delay(&self, attempt: u32) -> Duration;
73}
74
75/// Categorizes errors for appropriate handling.
76#[derive(Debug, Clone, PartialEq)]
77pub enum ErrorCategory {
78 /// Network connectivity issues
79 Network,
80 /// Server errors (5xx status codes)
81 Server,
82 /// Rate limiting exceeded
83 RateLimit,
84 /// Client errors (4xx status codes)
85 Client,
86 /// Transaction-related errors
87 Transaction,
88 /// Unknown or unclassified errors
89 Unknown,
90}