Wrap the duty manager in a future for its own thread
This commit is contained in:
parent
33d0f29221
commit
ffb3d94355
@ -32,3 +32,4 @@ tokio = "0.1.18"
|
||||
tokio-timer = "0.2.10"
|
||||
error-chain = "0.12.0"
|
||||
bincode = "^1.1.2"
|
||||
futures = "0.1.25"
|
||||
|
@ -8,6 +8,8 @@ pub use self::epoch_duties::EpochDutiesMap;
|
||||
use self::epoch_duties::{EpochDuties, EpochDutiesMapError};
|
||||
use self::traits::{BeaconNode, BeaconNodeError};
|
||||
use bls::PublicKey;
|
||||
use futures::Async;
|
||||
use slog::{debug, error, info};
|
||||
use slot_clock::SlotClock;
|
||||
use std::sync::Arc;
|
||||
use types::{ChainSpec, Epoch, Slot};
|
||||
@ -52,7 +54,7 @@ impl<T: SlotClock, U: BeaconNode> DutiesManager<T, U> {
|
||||
///
|
||||
/// The present `epoch` will be learned from the supplied `SlotClock`. In production this will
|
||||
/// be a wall-clock (e.g., system time, remote server time, etc.).
|
||||
pub fn update(&self, slot: Slot) -> Result<UpdateOutcome, Error> {
|
||||
fn update(&self, slot: Slot) -> Result<UpdateOutcome, Error> {
|
||||
let epoch = slot.epoch(self.spec.slots_per_epoch);
|
||||
|
||||
if let Some(duties) = self
|
||||
@ -75,6 +77,27 @@ impl<T: SlotClock, U: BeaconNode> DutiesManager<T, U> {
|
||||
Ok(UpdateOutcome::UnknownValidatorOrEpoch(epoch))
|
||||
}
|
||||
}
|
||||
|
||||
/// A future wrapping around `update()`. This will perform logic based upon the update
|
||||
/// process and complete once the update has completed.
|
||||
pub fn run_update(&self, slot: Slot, log: slog::Logger) -> Result<Async<()>, ()> {
|
||||
match self.update(slot) {
|
||||
Err(error) => error!(log, "Epoch duties poll error"; "error" => format!("{:?}", error)),
|
||||
Ok(UpdateOutcome::NoChange(epoch)) => {
|
||||
debug!(log, "No change in duties"; "epoch" => epoch)
|
||||
}
|
||||
Ok(UpdateOutcome::DutiesChanged(epoch, duties)) => {
|
||||
info!(log, "Duties changed (potential re-org)"; "epoch" => epoch, "duties" => format!("{:?}", duties))
|
||||
}
|
||||
Ok(UpdateOutcome::NewDuties(epoch, duties)) => {
|
||||
info!(log, "New duties obtained"; "epoch" => epoch, "duties" => format!("{:?}", duties))
|
||||
}
|
||||
Ok(UpdateOutcome::UnknownValidatorOrEpoch(epoch)) => {
|
||||
error!(log, "Epoch or validator unknown"; "epoch" => epoch)
|
||||
}
|
||||
};
|
||||
Ok(Async::Ready(()))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BeaconNodeError> for Error {
|
||||
|
@ -222,21 +222,22 @@ impl Service {
|
||||
// build requisite objects to pass to core thread.
|
||||
let duties_map = Arc::new(EpochDutiesMap::new(config.spec.slots_per_epoch));
|
||||
let epoch_map_for_attester = Arc::new(EpochMap::new(config.spec.slots_per_epoch));
|
||||
let manager = DutiesManager {
|
||||
let manager = Arc::new(DutiesManager {
|
||||
duties_map,
|
||||
pubkeys: keypairs.iter().map(|keypair| keypair.pk.clone()).collect(),
|
||||
spec: Arc::new(config.spec),
|
||||
slot_clock: service.slot_clock.clone(),
|
||||
beacon_node: service.validator_client.clone(),
|
||||
};
|
||||
});
|
||||
|
||||
// run the core thread
|
||||
runtime
|
||||
.block_on(interval.for_each(move |_| {
|
||||
let log = service.log.clone();
|
||||
// get the current slot
|
||||
let current_slot = match service.slot_clock.present_slot() {
|
||||
Err(e) => {
|
||||
error!(service.log, "SystemTimeError {:?}", e);
|
||||
error!(log, "SystemTimeError {:?}", e);
|
||||
return Ok(());
|
||||
}
|
||||
Ok(slot) => slot.expect("Genesis is in the future"),
|
||||
@ -247,28 +248,14 @@ impl Service {
|
||||
"The Timer should poll a new slot"
|
||||
);
|
||||
|
||||
info!(service.log, "Processing slot: {}", current_slot.as_u64());
|
||||
info!(log, "Processing slot: {}", current_slot.as_u64());
|
||||
|
||||
let cloned_manager = manager.clone();
|
||||
|
||||
// check for new duties
|
||||
// TODO: Convert to its own thread
|
||||
match manager.update(current_slot) {
|
||||
Err(error) => {
|
||||
error!(service.log, "Epoch duties poll error"; "error" => format!("{:?}", error))
|
||||
}
|
||||
Ok(UpdateOutcome::NoChange(epoch)) => {
|
||||
debug!(service.log, "No change in duties"; "epoch" => epoch)
|
||||
}
|
||||
Ok(UpdateOutcome::DutiesChanged(epoch, duties)) => {
|
||||
info!(service.log, "Duties changed (potential re-org)"; "epoch" => epoch, "duties" => format!("{:?}", duties))
|
||||
}
|
||||
Ok(UpdateOutcome::NewDuties(epoch, duties)) => {
|
||||
info!(service.log, "New duties obtained"; "epoch" => epoch, "duties" => format!("{:?}", duties))
|
||||
}
|
||||
Ok(UpdateOutcome::UnknownValidatorOrEpoch(epoch)) => {
|
||||
error!(service.log, "Epoch or validator unknown"; "epoch" => epoch)
|
||||
}
|
||||
};
|
||||
|
||||
tokio::spawn(futures::future::poll_fn(move || {
|
||||
cloned_manager.run_update(current_slot.clone(), log.clone())
|
||||
}));
|
||||
Ok(())
|
||||
}))
|
||||
.map_err(|e| format!("Service thread failed: {:?}", e))?;
|
||||
|
Loading…
Reference in New Issue
Block a user