// Copyright 2019-2021 Parity Technologies (UK) Ltd. // This file is part of Parity Bridges Common. // Parity Bridges Common is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // Parity Bridges Common is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with Parity Bridges Common. If not, see . use crate::{chain::Chain, client::Client}; use async_std::sync::{Arc, RwLock}; use async_trait::async_trait; use codec::Decode; use relay_utils::metrics::{ metric_name, register, F64SharedRef, Gauge, PrometheusError, Registry, StandaloneMetrics, F64, }; use sp_core::storage::StorageKey; use sp_runtime::{traits::UniqueSaturatedInto, FixedPointNumber}; use std::time::Duration; /// Storage value update interval (in blocks). const UPDATE_INTERVAL_IN_BLOCKS: u32 = 5; /// Metric that represents fixed-point runtime storage value as float gauge. #[derive(Clone, Debug)] pub struct FloatStorageValueMetric { client: Client, storage_key: StorageKey, maybe_default_value: Option, metric: Gauge, shared_value_ref: F64SharedRef, } impl FloatStorageValueMetric { /// Create new metric. pub fn new( registry: &Registry, prefix: Option<&str>, client: Client, storage_key: StorageKey, maybe_default_value: Option, name: String, help: String, ) -> Result { let shared_value_ref = Arc::new(RwLock::new(None)); Ok(FloatStorageValueMetric { client, storage_key, maybe_default_value, metric: register(Gauge::new(metric_name(prefix, &name), help)?, registry)?, shared_value_ref, }) } /// Get shared reference to metric value. pub fn shared_value_ref(&self) -> F64SharedRef { self.shared_value_ref.clone() } } #[async_trait] impl StandaloneMetrics for FloatStorageValueMetric where T: 'static + Decode + Send + Sync + FixedPointNumber, { fn update_interval(&self) -> Duration { C::AVERAGE_BLOCK_INTERVAL * UPDATE_INTERVAL_IN_BLOCKS } async fn update(&self) { let value = self .client .storage_value::(self.storage_key.clone(), None) .await .map(|maybe_storage_value| { maybe_storage_value.or(self.maybe_default_value).map(|storage_value| { storage_value.into_inner().unique_saturated_into() as f64 / T::DIV.unique_saturated_into() as f64 }) }) .map_err(drop); relay_utils::metrics::set_gauge_value(&self.metric, value); *self.shared_value_ref.write().await = value.ok().and_then(|x| x); } }