// Copyright 2021 Ian Jackson and contributors to Hippotat
-// SPDX-License-Identifier: AGPL-3.0-or-later
+// SPDX-License-Identifier: GPL-3.0-or-later
// There is NO WARRANTY.
use crate::prelude::*;
+// For clients only, really.
pub struct Reporter<'r> {
ic: &'r InstanceConfig,
+ successes: u64,
+ last_report: Option<Report>,
}
+#[derive(Debug)]
+struct Report {
+ when: Instant,
+ ok: Result<(),()>,
+}
+
+// Reporting strategy
+// - report all errors
+// - report first success after a period of lack of messages
+// - if error, report last success
+
impl<'r> Reporter<'r> {
pub fn new(ic: &'r InstanceConfig) -> Self { Reporter {
- ic
+ ic,
+ successes: 0,
+ last_report: None,
} }
- pub fn report<T>(&mut self, r: Result<T,AE>) -> Option<T> {
+ pub fn success(&mut self) {
+ self.successes += 1;
+ let now = Instant::now();
+ if let Some(rep) = &self.last_report {
+ if now - rep.when < match rep.ok {
+ Ok(()) => match self.ic.success_report_interval {
+ z if z == Duration::default() => return,
+ nonzero => nonzero,
+ },
+ Err(()) => self.ic.effective_http_timeout,
+ } {
+ return
+ }
+ }
+
+ info!(target:"hippotat", "{} ({}ok): running", self.ic, self.successes);
+ self.last_report = Some(Report { when: now, ok: Ok(()) });
+ }
+
+ pub fn filter<T>(&mut self, req_num: Option<ReqNum>, r: Result<T,AE>)
+ -> Option<T> {
+ let now = Instant::now();
match r {
Ok(t) => {
- // xxx something something success
Some(t)
},
Err(e) => {
- // xxx something something error
- error!("ERROR {} {:?}", self.ic, e);
+ let m = (||{
+ let mut m = self.ic.to_string();
+ if let Some(req_num) = req_num {
+ write!(m, " #{}", req_num)?;
+ }
+ if self.successes > 0 {
+ write!(m, " ({}ok)", self.successes)?;
+ self.successes = 0;
+ }
+ write!(m, ": {:?}", e)?;
+ Ok::<_,fmt::Error>(m)
+ })().unwrap();
+ warn!(target:"hippotat", "{}", m);
+ self.last_report = Some(Report { when: now, ok: Err(()) });
None
},
}