switchboard_solana/macros.rs
1/// Macro used to include code if the target_os is not 'solana'.
2/// This is intended to be used for code that is primarily for off-chain Switchboard Functions.
3#[macro_export]
4macro_rules! cfg_client {
5 ($($item:item)*) => {
6 $(
7 #[cfg_attr(doc_cfg, doc(cfg(feature = "client")))]
8 #[cfg(feature = "client")]
9 $item
10 )*
11 };
12}
13
14/// Macro used to include code only if the target_os is 'solana'.
15/// This is intended to be used for code that is primarily for on-chain programs.
16#[macro_export]
17macro_rules! cfg_program {
18 ($($item:item)*) => {
19 $(
20 #[cfg_attr(doc_cfg, doc(cfg(not(feature = "client"))))]
21 #[cfg(not(feature = "client"))]
22 $item
23 )*
24 };
25}
26
27/// Macro used to include code if the feature 'secrets' is enabled.
28/// This is intended to be used for code that is primarily for off-chain Switchboard Secrets.
29#[macro_export]
30macro_rules! cfg_secrets {
31 ($($item:item)*) => {
32 $(
33 #[cfg(all(feature = "secrets", not(target_os = "solana")))]
34 #[cfg_attr(doc_cfg, doc(cfg(all(feature = "secrets", not(target_os = "solana")))))]
35 $item
36 )*
37 };
38}
39
40/// Macro used to include code if the feature 'macros' is enabled.
41#[macro_export]
42macro_rules! cfg_macros {
43 ($($item:item)*) => {
44 $(
45 #[cfg(all(feature = "macros", not(target_os = "solana")))]
46 #[cfg_attr(doc_cfg, doc(cfg(all(feature = "macros", not(target_os = "solana")))))]
47 $item
48 )*
49 };
50}
51
52/// Macro used to include IPFS code if the feature 'ipfs' is enabled.
53#[macro_export]
54macro_rules! cfg_ipfs {
55 ($($item:item)*) => {
56 $(
57 #[cfg(all(feature = "ipfs", not(target_os = "solana")))]
58 #[cfg_attr(doc_cfg, doc(cfg(all(feature = "ipfs", not(target_os = "solana")))))]
59 $item
60 )*
61 };
62}
63
64/// Retry a given expression a specified number of times with a delay between each attempt.
65///
66/// # Arguments
67///
68/// * `attempts` - The number of attempts to make.
69/// * `delay_ms` - The delay in milliseconds between each attempt.
70/// * `expr` - The expression to be retried.
71///
72/// # Returns
73///
74/// Returns a `Result` containing the value of the expression if it succeeds within the specified number of attempts,
75/// or an error if it fails on all attempts.
76///
77/// # Examples
78/// ```
79/// use switchboard_solana::retry;
80///
81/// // Retry a blockhash fetch 3 times with a delay of 500ms in between each failure
82/// let blockhash = retry!(3, 500, rpc.get_latest_blockhash().await)
83/// .await
84/// .map_err(|e| SbError::SolanaBlockhashFetchError(Arc::new(e)))?;
85/// ```
86#[cfg(not(target_os = "solana"))]
87#[cfg_attr(doc_cfg, doc(cfg(not(target_os = "solana"))))]
88#[macro_export]
89macro_rules! retry {
90 ($attempts:expr, $delay_ms:expr, $expr:expr) => {{
91 async {
92 let mut attempts = $attempts;
93 loop {
94 match $expr {
95 Ok(val) => break Ok(val),
96 Err(_) if attempts > 1 => {
97 attempts -= 1;
98 tokio::time::sleep(tokio::time::Duration::from_millis($delay_ms)).await;
99 }
100 Err(e) => break Err(e),
101 }
102 }
103 }
104 }};
105}
106
107/// Retry a given expression a specified number of times with a delay between each attempt.
108/// This will block the current thread until a value is resolved or the maximum number of attempts is reached.
109///
110/// # Arguments
111///
112/// * `attempts` - The number of attempts to make.
113/// * `delay_ms` - The delay in milliseconds between each attempt.
114/// * `expr` - The expression to be retried.
115///
116/// # Returns
117///
118/// Returns a `Result` containing the value of the expression if it succeeds within the specified number of attempts,
119/// or an error if it fails on all attempts.
120///
121/// # Examples
122/// ```
123/// use switchboard_solana::blocking_retry;
124///
125/// // Retry a blockhash fetch 3 times with a delay of 500ms in between each failure
126/// let blockhash = blocking_retry!(3, 500, rpc.get_latest_blockhash())
127/// .map_err(|e| SbError::SolanaBlockhashFetchError(Arc::new(e)))?;
128/// ```
129#[cfg(not(target_os = "solana"))]
130#[cfg_attr(doc_cfg, doc(cfg(not(target_os = "solana"))))]
131#[macro_export]
132macro_rules! blocking_retry {
133 ($attempts:expr, $delay_ms:expr, $expr:expr) => {{
134 let mut attempts = $attempts;
135 loop {
136 match $expr {
137 Ok(val) => break Ok(val),
138 Err(_) if attempts > 1 => {
139 attempts -= 1;
140 std::thread::sleep(tokio::time::Duration::from_millis($delay_ms));
141 }
142 Err(e) => break Err(e),
143 }
144 }
145 }};
146}