referrerpolicy=no-referrer-when-downgrade

sc_service/task_manager/
prometheus_future.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
5
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19//! Wrapper around a `Future` that reports statistics about when the `Future` is polled.
20
21use futures::prelude::*;
22use prometheus_endpoint::{Counter, Histogram, U64};
23use std::{
24	fmt,
25	pin::Pin,
26	task::{Context, Poll},
27};
28
29/// Wraps around a `Future`. Report the polling duration to the `Histogram` and when the polling
30/// starts to the `Counter`.
31pub fn with_poll_durations<T>(
32	poll_duration: Histogram,
33	poll_start: Counter<U64>,
34	inner: T,
35) -> PrometheusFuture<T> {
36	PrometheusFuture { inner, poll_duration, poll_start }
37}
38
39/// Wraps around `Future` and adds diagnostics to it.
40#[pin_project::pin_project]
41#[derive(Clone)]
42pub struct PrometheusFuture<T> {
43	/// The inner future doing the actual work.
44	#[pin]
45	inner: T,
46	poll_duration: Histogram,
47	poll_start: Counter<U64>,
48}
49
50impl<T> Future for PrometheusFuture<T>
51where
52	T: Future,
53{
54	type Output = T::Output;
55
56	fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
57		let this = self.project();
58
59		this.poll_start.inc();
60		let _timer = this.poll_duration.start_timer();
61		Future::poll(this.inner, cx)
62
63		// `_timer` is dropped here and will observe the duration
64	}
65}
66
67impl<T> fmt::Debug for PrometheusFuture<T>
68where
69	T: fmt::Debug,
70{
71	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
72		fmt::Debug::fmt(&self.inner, f)
73	}
74}