mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-02 16:21:42 +00:00
Remove reprocess channel (#7437)
Partially https://github.com/sigp/lighthouse/issues/6291 This PR removes the reprocess event channel from being externally exposed. All work events are now sent through the single `BeaconProcessorSend` channel. I've introduced a new `Work::Reprocess` enum variant which we then use to schedule jobs for reprocess. I've also created a new scheduler module which will eventually house the different scheduler impls. This is all needed as an initial step to generalize the beacon processor A "full" implementation for the generalized beacon processor can be found here https://github.com/sigp/lighthouse/pull/6448 I'm going to try to break up the full implementation into smaller PR's so it can actually be reviewed
This commit is contained in:
@@ -47,6 +47,7 @@ use lighthouse_network::{MessageId, NetworkGlobals, PeerId};
|
||||
use logging::crit;
|
||||
use logging::TimeLatch;
|
||||
use parking_lot::Mutex;
|
||||
pub use scheduler::work_reprocessing_queue;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use slot_clock::SlotClock;
|
||||
use std::cmp;
|
||||
@@ -73,7 +74,7 @@ use work_reprocessing_queue::{
|
||||
use work_reprocessing_queue::{IgnoredRpcBlock, QueuedSamplingRequest};
|
||||
|
||||
mod metrics;
|
||||
pub mod work_reprocessing_queue;
|
||||
pub mod scheduler;
|
||||
|
||||
/// The maximum size of the channel for work events to the `BeaconProcessor`.
|
||||
///
|
||||
@@ -264,22 +265,16 @@ impl Default for BeaconProcessorConfig {
|
||||
pub struct BeaconProcessorChannels<E: EthSpec> {
|
||||
pub beacon_processor_tx: BeaconProcessorSend<E>,
|
||||
pub beacon_processor_rx: mpsc::Receiver<WorkEvent<E>>,
|
||||
pub work_reprocessing_tx: mpsc::Sender<ReprocessQueueMessage>,
|
||||
pub work_reprocessing_rx: mpsc::Receiver<ReprocessQueueMessage>,
|
||||
}
|
||||
|
||||
impl<E: EthSpec> BeaconProcessorChannels<E> {
|
||||
pub fn new(config: &BeaconProcessorConfig) -> Self {
|
||||
let (beacon_processor_tx, beacon_processor_rx) =
|
||||
mpsc::channel(config.max_work_event_queue_len);
|
||||
let (work_reprocessing_tx, work_reprocessing_rx) =
|
||||
mpsc::channel(config.max_scheduled_work_queue_len);
|
||||
|
||||
Self {
|
||||
beacon_processor_tx: BeaconProcessorSend(beacon_processor_tx),
|
||||
beacon_processor_rx,
|
||||
work_reprocessing_rx,
|
||||
work_reprocessing_tx,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -638,6 +633,7 @@ pub enum Work<E: EthSpec> {
|
||||
LightClientUpdatesByRangeRequest(BlockingFn),
|
||||
ApiRequestP0(BlockingOrAsync),
|
||||
ApiRequestP1(BlockingOrAsync),
|
||||
Reprocess(ReprocessQueueMessage),
|
||||
}
|
||||
|
||||
impl<E: EthSpec> fmt::Debug for Work<E> {
|
||||
@@ -692,6 +688,7 @@ pub enum WorkType {
|
||||
LightClientUpdatesByRangeRequest,
|
||||
ApiRequestP0,
|
||||
ApiRequestP1,
|
||||
Reprocess,
|
||||
}
|
||||
|
||||
impl<E: EthSpec> Work<E> {
|
||||
@@ -750,6 +747,7 @@ impl<E: EthSpec> Work<E> {
|
||||
}
|
||||
Work::ApiRequestP0 { .. } => WorkType::ApiRequestP0,
|
||||
Work::ApiRequestP1 { .. } => WorkType::ApiRequestP1,
|
||||
Work::Reprocess { .. } => WorkType::Reprocess,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -774,7 +772,7 @@ struct InboundEvents<E: EthSpec> {
|
||||
/// Used by upstream processes to send new work to the `BeaconProcessor`.
|
||||
event_rx: mpsc::Receiver<WorkEvent<E>>,
|
||||
/// Used internally for queuing work ready to be re-processed.
|
||||
reprocess_work_rx: mpsc::Receiver<ReadyWork>,
|
||||
ready_work_rx: mpsc::Receiver<ReadyWork>,
|
||||
}
|
||||
|
||||
impl<E: EthSpec> Stream for InboundEvents<E> {
|
||||
@@ -795,7 +793,7 @@ impl<E: EthSpec> Stream for InboundEvents<E> {
|
||||
|
||||
// Poll for delayed blocks before polling for new work. It might be the case that a delayed
|
||||
// block is required to successfully process some new work.
|
||||
match self.reprocess_work_rx.poll_recv(cx) {
|
||||
match self.ready_work_rx.poll_recv(cx) {
|
||||
Poll::Ready(Some(ready_work)) => {
|
||||
return Poll::Ready(Some(InboundEvent::ReprocessingWork(ready_work.into())));
|
||||
}
|
||||
@@ -846,8 +844,6 @@ impl<E: EthSpec> BeaconProcessor<E> {
|
||||
pub fn spawn_manager<S: SlotClock + 'static>(
|
||||
mut self,
|
||||
event_rx: mpsc::Receiver<WorkEvent<E>>,
|
||||
work_reprocessing_tx: mpsc::Sender<ReprocessQueueMessage>,
|
||||
work_reprocessing_rx: mpsc::Receiver<ReprocessQueueMessage>,
|
||||
work_journal_tx: Option<mpsc::Sender<&'static str>>,
|
||||
slot_clock: S,
|
||||
maximum_gossip_clock_disparity: Duration,
|
||||
@@ -935,9 +931,13 @@ impl<E: EthSpec> BeaconProcessor<E> {
|
||||
// receive them back once they are ready (`ready_work_rx`).
|
||||
let (ready_work_tx, ready_work_rx) =
|
||||
mpsc::channel::<ReadyWork>(self.config.max_scheduled_work_queue_len);
|
||||
|
||||
let (reprocess_work_tx, reprocess_work_rx) =
|
||||
mpsc::channel::<ReprocessQueueMessage>(self.config.max_scheduled_work_queue_len);
|
||||
|
||||
spawn_reprocess_scheduler(
|
||||
ready_work_tx,
|
||||
work_reprocessing_rx,
|
||||
reprocess_work_rx,
|
||||
&self.executor,
|
||||
Arc::new(slot_clock),
|
||||
maximum_gossip_clock_disparity,
|
||||
@@ -951,7 +951,7 @@ impl<E: EthSpec> BeaconProcessor<E> {
|
||||
let mut inbound_events = InboundEvents {
|
||||
idle_rx,
|
||||
event_rx,
|
||||
reprocess_work_rx: ready_work_rx,
|
||||
ready_work_rx,
|
||||
};
|
||||
|
||||
let enable_backfill_rate_limiting = self.config.enable_backfill_rate_limiting;
|
||||
@@ -965,7 +965,7 @@ impl<E: EthSpec> BeaconProcessor<E> {
|
||||
Some(InboundEvent::WorkEvent(event)) if enable_backfill_rate_limiting => {
|
||||
match QueuedBackfillBatch::try_from(event) {
|
||||
Ok(backfill_batch) => {
|
||||
match work_reprocessing_tx
|
||||
match reprocess_work_tx
|
||||
.try_send(ReprocessQueueMessage::BackfillSync(backfill_batch))
|
||||
{
|
||||
Err(e) => {
|
||||
@@ -1027,8 +1027,10 @@ impl<E: EthSpec> BeaconProcessor<E> {
|
||||
.unwrap_or(WORKER_FREED);
|
||||
|
||||
// We don't care if this message was successfully sent, we only use the journal
|
||||
// during testing.
|
||||
let _ = work_journal_tx.try_send(id);
|
||||
// during testing. We also ignore reprocess messages to ensure our test cases can pass.
|
||||
if id != "reprocess" {
|
||||
let _ = work_journal_tx.try_send(id);
|
||||
}
|
||||
}
|
||||
|
||||
let can_spawn = self.current_workers < self.config.max_workers;
|
||||
@@ -1318,6 +1320,14 @@ impl<E: EthSpec> BeaconProcessor<E> {
|
||||
let work_type = work.to_type();
|
||||
|
||||
match work {
|
||||
Work::Reprocess(work_event) => {
|
||||
if let Err(e) = reprocess_work_tx.try_send(work_event) {
|
||||
error!(
|
||||
error = ?e,
|
||||
"Failed to reprocess work event"
|
||||
)
|
||||
}
|
||||
}
|
||||
_ if can_spawn => self.spawn_worker(work, idle_tx),
|
||||
Work::GossipAttestation { .. } => attestation_queue.push(work),
|
||||
// Attestation batches are formed internally within the
|
||||
@@ -1488,6 +1498,7 @@ impl<E: EthSpec> BeaconProcessor<E> {
|
||||
WorkType::LightClientUpdatesByRangeRequest => lc_update_range_queue.len(),
|
||||
WorkType::ApiRequestP0 => api_request_p0_queue.len(),
|
||||
WorkType::ApiRequestP1 => api_request_p1_queue.len(),
|
||||
WorkType::Reprocess => 0,
|
||||
};
|
||||
metrics::observe_vec(
|
||||
&metrics::BEACON_PROCESSOR_QUEUE_LENGTH,
|
||||
@@ -1639,6 +1650,7 @@ impl<E: EthSpec> BeaconProcessor<E> {
|
||||
| Work::LightClientUpdatesByRangeRequest(process_fn) => {
|
||||
task_spawner.spawn_blocking(process_fn)
|
||||
}
|
||||
Work::Reprocess(_) => {}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
1
beacon_node/beacon_processor/src/scheduler/mod.rs
Normal file
1
beacon_node/beacon_processor/src/scheduler/mod.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub mod work_reprocessing_queue;
|
||||
Reference in New Issue
Block a user