taler-rust

GNU Taler code in Rust. Largely core banking integrations.
Log | Files | Refs | Submodules | README | LICENSE

lib.rs (2931B)


      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::{future::Future, 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 cli;
     31 pub mod config;
     32 pub mod db;
     33 pub mod error;
     34 pub mod error_code;
     35 pub mod json_file;
     36 pub mod log;
     37 pub mod types;
     38 
     39 #[derive(clap::Parser, Debug, Clone)]
     40 pub struct CommonArgs {
     41     /// Specifies the configuration file
     42     #[clap(long, short)]
     43     #[arg(global = true)]
     44     config: Option<PathBuf>,
     45 
     46     /// Configure logging to use LOGLEVEL
     47     #[clap(long, short('L'))]
     48     #[arg(global = true)]
     49     log: Option<tracing::Level>,
     50 }
     51 
     52 pub fn taler_main<F: Future<Output = Result<(), anyhow::Error>>>(
     53     src: ConfigSource,
     54     args: CommonArgs,
     55     app: impl FnOnce(Config) -> F,
     56 ) {
     57     taler_logger(args.log).init();
     58     let cfg = match Config::from_file(src, args.config) {
     59         Ok(cfg) => cfg,
     60         Err(err) => {
     61             error!(target: "config", "{}", err);
     62             std::process::exit(1);
     63         }
     64     };
     65 
     66     // Setup async runtime
     67     let runtime = tokio::runtime::Builder::new_multi_thread()
     68         .enable_all()
     69         .build()
     70         .unwrap();
     71 
     72     // Run app
     73     let result = runtime.block_on(app(cfg));
     74     if let Err(err) = result {
     75         error!(target: "cli", "{}", err);
     76         std::process::exit(1);
     77     }
     78 }
     79 
     80 /// Infinite exponential backoff with decorrelated jitter
     81 pub struct ExpoBackoffDecorr {
     82     base: u32,
     83     max: u32,
     84     factor: f32,
     85     sleep: u32,
     86 }
     87 
     88 impl ExpoBackoffDecorr {
     89     pub fn new(base: u32, max: u32, factor: f32) -> Self {
     90         Self {
     91             base,
     92             max,
     93             factor,
     94             sleep: base,
     95         }
     96     }
     97 
     98     pub fn backoff(&mut self) -> Duration {
     99         self.sleep =
    100             rand::random_range(self.base..(self.sleep as f32 * self.factor) as u32).min(self.max);
    101         Duration::from_millis(self.sleep as u64)
    102     }
    103 
    104     pub fn reset(&mut self) {
    105         self.sleep = self.base
    106     }
    107 }
    108 
    109 impl Default for ExpoBackoffDecorr {
    110     fn default() -> Self {
    111         Self::new(400, 30 * 1000, 2.5)
    112     }
    113 }