lib.rs (3045B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2024, 2025, 2026 Taler Systems SA 4 5 TALER is free software; you can redistribute it and/or modify it under the 6 terms of the GNU Affero General Public License as published by the Free Software 7 Foundation; either version 3, or (at your option) any later version. 8 9 TALER is distributed in the hope that it will be useful, but WITHOUT ANY 10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. 12 13 You should have received a copy of the GNU Affero General Public License along with 14 TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 */ 16 17 use std::{path::PathBuf, time::Duration}; 18 19 use config::{Config, parser::ConfigSource}; 20 use tracing::error; 21 use tracing_subscriber::util::SubscriberInitExt; 22 23 use crate::log::taler_logger; 24 25 pub mod api_common; 26 pub mod api_params; 27 pub mod api_revenue; 28 pub mod api_transfer; 29 pub mod api_wire; 30 pub mod bench; 31 pub mod cli; 32 pub mod config; 33 pub mod db; 34 pub mod encoding; 35 pub mod error; 36 pub mod error_code; 37 pub mod json_file; 38 pub mod log; 39 pub mod types; 40 41 #[derive(clap::Parser, Debug, Clone)] 42 pub struct CommonArgs { 43 /// Specifies the configuration file 44 #[clap(long, short)] 45 #[arg(global = true)] 46 config: Option<PathBuf>, 47 48 /// Configure logging to use LOGLEVEL 49 #[clap(long, short('L'))] 50 #[arg(global = true)] 51 log: Option<tracing::Level>, 52 } 53 54 pub fn taler_main( 55 src: ConfigSource, 56 args: CommonArgs, 57 app: impl AsyncFnOnce(Config) -> Result<(), anyhow::Error>, 58 ) { 59 taler_logger(args.log).init(); 60 let cfg = match Config::from_file(src, args.config) { 61 Ok(cfg) => cfg, 62 Err(err) => { 63 error!(target: "config", "{}", err); 64 std::process::exit(1); 65 } 66 }; 67 68 // Setup async runtime 69 let runtime = tokio::runtime::Builder::new_multi_thread() 70 .enable_all() 71 .build() 72 .unwrap(); 73 74 // Run app 75 let result = runtime.block_on(app(cfg)); 76 if let Err(err) = result { 77 error!(target: "cli", "{}", err); 78 std::process::exit(1); 79 } 80 } 81 82 /// Infinite exponential backoff with decorrelated jitter 83 pub struct ExpoBackoffDecorr { 84 base: u32, 85 max: u32, 86 factor: f32, 87 sleep: u32, 88 } 89 90 impl ExpoBackoffDecorr { 91 pub fn new(base: Duration, max: Duration, factor: f32) -> Self { 92 Self { 93 base: base.as_millis() as u32, 94 max: max.as_millis() as u32, 95 factor, 96 sleep: base.as_millis() as u32, 97 } 98 } 99 100 pub fn backoff(&mut self) -> Duration { 101 self.sleep = 102 rand::random_range(self.base..(self.sleep as f32 * self.factor) as u32).min(self.max); 103 Duration::from_millis(self.sleep as u64) 104 } 105 106 pub fn reset(&mut self) { 107 self.sleep = self.base 108 } 109 } 110 111 impl Default for ExpoBackoffDecorr { 112 fn default() -> Self { 113 Self::new(Duration::from_millis(400), Duration::from_secs(30), 2.5) 114 } 115 }