#![doc = include_str!("../README.md")]
use near_chain_configs::UpdatableClientConfig;
use near_o11y::log_config::LogConfig;
use near_primitives::validator_signer::ValidatorSigner;
use near_time::Clock;
use std::path::PathBuf;
use std::sync::Arc;
use tokio::sync::broadcast::Sender;
mod metrics;
#[derive(Clone, Default)]
pub enum UpdatableValidatorSigner {
#[default]
KeyExistenceNotDetermined,
MaybeKey(Option<Arc<ValidatorSigner>>),
}
#[derive(Clone, Default)]
pub struct UpdatableConfigs {
pub log_config: Option<LogConfig>,
pub client_config: Option<UpdatableClientConfig>,
pub validator_signer: UpdatableValidatorSigner,
}
#[derive(Default)]
pub struct UpdatableConfigLoader {
tx: Option<Sender<Result<UpdatableConfigs, Arc<UpdatableConfigLoaderError>>>>,
}
#[derive(thiserror::Error, Debug)]
#[non_exhaustive]
pub enum UpdatableConfigLoaderError {
#[error("Failed to parse a dynamic config file {file:?}: {err:?}")]
Parse { file: PathBuf, err: serde_json::Error },
#[error("Can't open or read a dynamic config file {file:?}: {err:?}")]
OpenAndRead { file: PathBuf, err: std::io::Error },
#[error("Can't open or read the config file {file:?}: {err:?}")]
ConfigFileError { file: PathBuf, err: anyhow::Error },
#[error("Can't open or read the validator key file {file:?}: {err:?}")]
ValidatorKeyFileError { file: PathBuf, err: anyhow::Error },
#[error("One or multiple dynamic config files reload errors {0:?}")]
Errors(Vec<UpdatableConfigLoaderError>),
#[error("No home dir set")]
NoHomeDir(),
}
impl UpdatableConfigLoader {
pub fn new(
updatable_configs: UpdatableConfigs,
tx: Sender<Result<UpdatableConfigs, Arc<UpdatableConfigLoaderError>>>,
) -> Self {
let mut result = Self { tx: Some(tx) };
result.reload(Ok(updatable_configs));
result
}
pub fn reload(
&mut self,
updatable_configs: Result<UpdatableConfigs, UpdatableConfigLoaderError>,
) {
match updatable_configs {
Ok(updatable_configs) => {
near_o11y::reload_log_config(updatable_configs.log_config.as_ref());
self.tx.as_ref().map(|tx| tx.send(Ok(updatable_configs.clone())));
Self::update_metrics();
}
Err(err) => {
self.tx.as_ref().map(|tx| tx.send(Err(Arc::new(err))));
}
}
}
fn update_metrics() {
metrics::CONFIG_RELOAD_TIMESTAMP.set(Clock::real().now_utc().unix_timestamp());
metrics::CONFIG_RELOADS.inc();
}
}