Files
solana/src/logger.rs

78 lines
2.4 KiB
Rust
Raw Normal View History

2018-03-03 14:24:32 -07:00
//! The `logger` crate provides an object for generating a Proof-of-History.
//! It logs Event items on behalf of its users. It continuously generates
//! new hashes, only stopping to check if it has been sent an Event item. It
//! tags each Event with an Entry and sends it back. The Entry includes the
//! Event, the latest hash, and the number of hashes since the last event.
//! The resulting stream of entries represents ordered events in time.
2018-03-04 07:28:51 -07:00
use std::sync::mpsc::{Receiver, SyncSender, TryRecvError};
2018-03-03 14:24:32 -07:00
use std::time::{Duration, Instant};
2018-03-06 17:20:37 -07:00
use hash::Sha256Hash;
use log::{create_entry_mut, Entry};
use event::Event;
2018-03-03 14:24:32 -07:00
use serde::Serialize;
use std::fmt::Debug;
use serde_json;
2018-03-03 14:24:32 -07:00
#[derive(Debug, PartialEq, Eq)]
pub enum ExitReason {
RecvDisconnected,
SendDisconnected,
}
pub struct Logger<T> {
pub sender: SyncSender<Entry<T>>,
pub receiver: Receiver<Event<T>>,
2018-03-04 07:34:38 -07:00
pub last_id: Sha256Hash,
2018-03-03 14:24:32 -07:00
pub num_hashes: u64,
pub num_ticks: u64,
}
impl<T: Serialize + Clone + Debug> Logger<T> {
pub fn new(
receiver: Receiver<Event<T>>,
sender: SyncSender<Entry<T>>,
start_hash: Sha256Hash,
) -> Self {
Logger {
receiver,
sender,
2018-03-04 07:34:38 -07:00
last_id: start_hash,
2018-03-03 14:24:32 -07:00
num_hashes: 0,
num_ticks: 0,
}
}
pub fn log_event(&mut self, event: Event<T>) -> Result<Entry<T>, ExitReason> {
let entry = create_entry_mut(&mut self.last_id, &mut self.num_hashes, event);
println!("{}", serde_json::to_string(&entry).unwrap());
Ok(entry)
2018-03-03 14:24:32 -07:00
}
pub fn process_events(
2018-03-03 14:24:32 -07:00
&mut self,
epoch: Instant,
ms_per_tick: Option<u64>,
) -> Result<(), ExitReason> {
2018-03-03 14:24:32 -07:00
loop {
if let Some(ms) = ms_per_tick {
if epoch.elapsed() > Duration::from_millis((self.num_ticks + 1) * ms) {
self.log_event(Event::Tick)?;
self.num_ticks += 1;
}
}
2018-03-03 14:24:32 -07:00
match self.receiver.try_recv() {
Ok(event) => {
let entry = self.log_event(event)?;
self.sender
.send(entry)
.or(Err(ExitReason::SendDisconnected))?;
2018-03-03 14:24:32 -07:00
}
Err(TryRecvError::Empty) => return Ok(()),
Err(TryRecvError::Disconnected) => return Err(ExitReason::RecvDisconnected),
};
2018-03-03 14:24:32 -07:00
}
}
}