diff --git a/README.md b/README.md index e0d4fb0f3..236edf56b 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ fn create_log(hist: &Historian) -> Result<(), SendError> { fn main() { let seed = Sha256Hash::default(); - let hist = Historian::new(&seed); + let hist = Historian::new(&seed, None); create_log(&hist).expect("send error"); drop(hist.sender); let entries: Vec = hist.receiver.iter().collect(); diff --git a/src/bin/demo.rs b/src/bin/demo.rs index ac7864c61..0799faa93 100644 --- a/src/bin/demo.rs +++ b/src/bin/demo.rs @@ -16,7 +16,7 @@ fn create_log(hist: &Historian) -> Result<(), SendError> { fn main() { let seed = Sha256Hash::default(); - let hist = Historian::new(&seed); + let hist = Historian::new(&seed, None); create_log(&hist).expect("send error"); drop(hist.sender); let entries: Vec = hist.receiver.iter().collect(); diff --git a/src/historian.rs b/src/historian.rs index f958e0b45..09815790a 100644 --- a/src/historian.rs +++ b/src/historian.rs @@ -7,6 +7,7 @@ use std::thread::JoinHandle; use std::sync::mpsc::{Receiver, Sender}; +use std::time::{Duration, SystemTime}; use log::{extend_and_hash, hash, Entry, Event, Sha256Hash}; pub struct Historian { @@ -20,29 +21,48 @@ pub enum ExitReason { RecvDisconnected, SendDisconnected, } +fn log_event( + sender: &Sender, + num_hashes: &mut u64, + end_hash: &mut Sha256Hash, + event: Event, +) -> Result<(), (Entry, ExitReason)> { + if let Event::UserDataKey(key) = event { + *end_hash = extend_and_hash(end_hash, &key); + } + let entry = Entry { + end_hash: *end_hash, + num_hashes: *num_hashes, + event, + }; + if let Err(_) = sender.send(entry.clone()) { + return Err((entry, ExitReason::SendDisconnected)); + } + *num_hashes = 0; + Ok(()) +} fn log_events( receiver: &Receiver, sender: &Sender, num_hashes: &mut u64, end_hash: &mut Sha256Hash, + epoch: SystemTime, + num_ticks: &mut u64, + ms_per_tick: Option, ) -> Result<(), (Entry, ExitReason)> { use std::sync::mpsc::TryRecvError; loop { + if let Some(ms) = ms_per_tick { + let now = SystemTime::now(); + if now > epoch + Duration::from_millis((*num_ticks + 1) * ms) { + log_event(sender, num_hashes, end_hash, Event::Tick)?; + *num_ticks += 1; + } + } match receiver.try_recv() { Ok(event) => { - if let Event::UserDataKey(key) = event { - *end_hash = extend_and_hash(end_hash, &key); - } - let entry = Entry { - end_hash: *end_hash, - num_hashes: *num_hashes, - event, - }; - if let Err(_) = sender.send(entry.clone()) { - return Err((entry, ExitReason::SendDisconnected)); - } - *num_hashes = 0; + log_event(sender, num_hashes, end_hash, event)?; } Err(TryRecvError::Empty) => { return Ok(()); @@ -63,6 +83,7 @@ fn log_events( /// sending back Entry messages until either the receiver or sender channel is closed. pub fn create_logger( start_hash: Sha256Hash, + ms_per_tick: Option, receiver: Receiver, sender: Sender, ) -> JoinHandle<(Entry, ExitReason)> { @@ -70,8 +91,18 @@ pub fn create_logger( thread::spawn(move || { let mut end_hash = start_hash; let mut num_hashes = 0; + let mut num_ticks = 0; + let epoch = SystemTime::now(); loop { - if let Err(err) = log_events(&receiver, &sender, &mut num_hashes, &mut end_hash) { + if let Err(err) = log_events( + &receiver, + &sender, + &mut num_hashes, + &mut end_hash, + epoch, + &mut num_ticks, + ms_per_tick, + ) { return err; } end_hash = hash(&end_hash); @@ -81,11 +112,11 @@ pub fn create_logger( } impl Historian { - pub fn new(start_hash: &Sha256Hash) -> Self { + pub fn new(start_hash: &Sha256Hash, ms_per_tick: Option) -> Self { use std::sync::mpsc::channel; let (sender, event_receiver) = channel(); let (entry_sender, receiver) = channel(); - let thread_hdl = create_logger(*start_hash, event_receiver, entry_sender); + let thread_hdl = create_logger(*start_hash, ms_per_tick, event_receiver, entry_sender); Historian { sender, receiver, @@ -105,7 +136,7 @@ mod tests { use std::time::Duration; let zero = Sha256Hash::default(); - let hist = Historian::new(&zero); + let hist = Historian::new(&zero, None); hist.sender.send(Event::Tick).unwrap(); sleep(Duration::new(0, 1_000_000)); @@ -129,7 +160,7 @@ mod tests { #[test] fn test_historian_closed_sender() { let zero = Sha256Hash::default(); - let hist = Historian::new(&zero); + let hist = Historian::new(&zero, None); drop(hist.receiver); hist.sender.send(Event::Tick).unwrap(); assert_eq!(