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}