mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-07 00:42:42 +00:00
Use spawn_async in ByRoot handling workers (#5557)
* Use spawn_async in ByRoot handling workers * box large variants
This commit is contained in:
@@ -571,7 +571,7 @@ pub enum BlockingOrAsync {
|
|||||||
/// queuing specifics.
|
/// queuing specifics.
|
||||||
pub enum Work<E: EthSpec> {
|
pub enum Work<E: EthSpec> {
|
||||||
GossipAttestation {
|
GossipAttestation {
|
||||||
attestation: GossipAttestationPackage<E>,
|
attestation: Box<GossipAttestationPackage<E>>,
|
||||||
process_individual: Box<dyn FnOnce(GossipAttestationPackage<E>) + Send + Sync>,
|
process_individual: Box<dyn FnOnce(GossipAttestationPackage<E>) + Send + Sync>,
|
||||||
process_batch: Box<dyn FnOnce(Vec<GossipAttestationPackage<E>>) + Send + Sync>,
|
process_batch: Box<dyn FnOnce(Vec<GossipAttestationPackage<E>>) + Send + Sync>,
|
||||||
},
|
},
|
||||||
@@ -583,7 +583,7 @@ pub enum Work<E: EthSpec> {
|
|||||||
process_batch: Box<dyn FnOnce(Vec<GossipAttestationPackage<E>>) + Send + Sync>,
|
process_batch: Box<dyn FnOnce(Vec<GossipAttestationPackage<E>>) + Send + Sync>,
|
||||||
},
|
},
|
||||||
GossipAggregate {
|
GossipAggregate {
|
||||||
aggregate: GossipAggregatePackage<E>,
|
aggregate: Box<GossipAggregatePackage<E>>,
|
||||||
process_individual: Box<dyn FnOnce(GossipAggregatePackage<E>) + Send + Sync>,
|
process_individual: Box<dyn FnOnce(GossipAggregatePackage<E>) + Send + Sync>,
|
||||||
process_batch: Box<dyn FnOnce(Vec<GossipAggregatePackage<E>>) + Send + Sync>,
|
process_batch: Box<dyn FnOnce(Vec<GossipAggregatePackage<E>>) + Send + Sync>,
|
||||||
},
|
},
|
||||||
@@ -624,8 +624,8 @@ pub enum Work<E: EthSpec> {
|
|||||||
ChainSegment(AsyncFn),
|
ChainSegment(AsyncFn),
|
||||||
ChainSegmentBackfill(AsyncFn),
|
ChainSegmentBackfill(AsyncFn),
|
||||||
Status(BlockingFn),
|
Status(BlockingFn),
|
||||||
BlocksByRangeRequest(BlockingFnWithManualSendOnIdle),
|
BlocksByRangeRequest(AsyncFn),
|
||||||
BlocksByRootsRequest(BlockingFnWithManualSendOnIdle),
|
BlocksByRootsRequest(AsyncFn),
|
||||||
BlobsByRangeRequest(BlockingFn),
|
BlobsByRangeRequest(BlockingFn),
|
||||||
BlobsByRootsRequest(BlockingFn),
|
BlobsByRootsRequest(BlockingFn),
|
||||||
GossipBlsToExecutionChange(BlockingFn),
|
GossipBlsToExecutionChange(BlockingFn),
|
||||||
@@ -1015,7 +1015,7 @@ impl<E: EthSpec> BeaconProcessor<E> {
|
|||||||
process_individual: _,
|
process_individual: _,
|
||||||
process_batch,
|
process_batch,
|
||||||
} => {
|
} => {
|
||||||
aggregates.push(aggregate);
|
aggregates.push(*aggregate);
|
||||||
if process_batch_opt.is_none() {
|
if process_batch_opt.is_none() {
|
||||||
process_batch_opt = Some(process_batch);
|
process_batch_opt = Some(process_batch);
|
||||||
}
|
}
|
||||||
@@ -1075,7 +1075,7 @@ impl<E: EthSpec> BeaconProcessor<E> {
|
|||||||
process_individual: _,
|
process_individual: _,
|
||||||
process_batch,
|
process_batch,
|
||||||
} => {
|
} => {
|
||||||
attestations.push(attestation);
|
attestations.push(*attestation);
|
||||||
if process_batch_opt.is_none() {
|
if process_batch_opt.is_none() {
|
||||||
process_batch_opt = Some(process_batch);
|
process_batch_opt = Some(process_batch);
|
||||||
}
|
}
|
||||||
@@ -1445,7 +1445,7 @@ impl<E: EthSpec> BeaconProcessor<E> {
|
|||||||
process_individual,
|
process_individual,
|
||||||
process_batch: _,
|
process_batch: _,
|
||||||
} => task_spawner.spawn_blocking(move || {
|
} => task_spawner.spawn_blocking(move || {
|
||||||
process_individual(attestation);
|
process_individual(*attestation);
|
||||||
}),
|
}),
|
||||||
Work::GossipAttestationBatch {
|
Work::GossipAttestationBatch {
|
||||||
attestations,
|
attestations,
|
||||||
@@ -1458,7 +1458,7 @@ impl<E: EthSpec> BeaconProcessor<E> {
|
|||||||
process_individual,
|
process_individual,
|
||||||
process_batch: _,
|
process_batch: _,
|
||||||
} => task_spawner.spawn_blocking(move || {
|
} => task_spawner.spawn_blocking(move || {
|
||||||
process_individual(aggregate);
|
process_individual(*aggregate);
|
||||||
}),
|
}),
|
||||||
Work::GossipAggregateBatch {
|
Work::GossipAggregateBatch {
|
||||||
aggregates,
|
aggregates,
|
||||||
@@ -1493,7 +1493,7 @@ impl<E: EthSpec> BeaconProcessor<E> {
|
|||||||
task_spawner.spawn_blocking(process_fn)
|
task_spawner.spawn_blocking(process_fn)
|
||||||
}
|
}
|
||||||
Work::BlocksByRangeRequest(work) | Work::BlocksByRootsRequest(work) => {
|
Work::BlocksByRangeRequest(work) | Work::BlocksByRootsRequest(work) => {
|
||||||
task_spawner.spawn_blocking_with_manual_send_idle(work)
|
task_spawner.spawn_async(work)
|
||||||
}
|
}
|
||||||
Work::ChainSegmentBackfill(process_fn) => task_spawner.spawn_async(process_fn),
|
Work::ChainSegmentBackfill(process_fn) => task_spawner.spawn_async(process_fn),
|
||||||
Work::ApiRequestP0(process_fn) | Work::ApiRequestP1(process_fn) => match process_fn {
|
Work::ApiRequestP0(process_fn) | Work::ApiRequestP1(process_fn) => match process_fn {
|
||||||
@@ -1555,23 +1555,6 @@ impl TaskSpawner {
|
|||||||
WORKER_TASK_NAME,
|
WORKER_TASK_NAME,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Spawn a blocking task, passing the `SendOnDrop` into the task.
|
|
||||||
///
|
|
||||||
/// ## Notes
|
|
||||||
///
|
|
||||||
/// Users must ensure the `SendOnDrop` is dropped at the appropriate time!
|
|
||||||
pub fn spawn_blocking_with_manual_send_idle<F>(self, task: F)
|
|
||||||
where
|
|
||||||
F: FnOnce(SendOnDrop) + Send + 'static,
|
|
||||||
{
|
|
||||||
self.executor.spawn_blocking(
|
|
||||||
|| {
|
|
||||||
task(self.send_idle_on_drop);
|
|
||||||
},
|
|
||||||
WORKER_TASK_NAME,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This struct will send a message on `self.tx` when it is dropped. An error will be logged on
|
/// This struct will send a message on `self.tx` when it is dropped. An error will be logged on
|
||||||
|
|||||||
@@ -102,14 +102,14 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
|
|||||||
self.try_send(BeaconWorkEvent {
|
self.try_send(BeaconWorkEvent {
|
||||||
drop_during_sync: true,
|
drop_during_sync: true,
|
||||||
work: Work::GossipAttestation {
|
work: Work::GossipAttestation {
|
||||||
attestation: GossipAttestationPackage {
|
attestation: Box::new(GossipAttestationPackage {
|
||||||
message_id,
|
message_id,
|
||||||
peer_id,
|
peer_id,
|
||||||
attestation: Box::new(attestation),
|
attestation: Box::new(attestation),
|
||||||
subnet_id,
|
subnet_id,
|
||||||
should_import,
|
should_import,
|
||||||
seen_timestamp,
|
seen_timestamp,
|
||||||
},
|
}),
|
||||||
process_individual: Box::new(process_individual),
|
process_individual: Box::new(process_individual),
|
||||||
process_batch: Box::new(process_batch),
|
process_batch: Box::new(process_batch),
|
||||||
},
|
},
|
||||||
@@ -148,13 +148,13 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
|
|||||||
self.try_send(BeaconWorkEvent {
|
self.try_send(BeaconWorkEvent {
|
||||||
drop_during_sync: true,
|
drop_during_sync: true,
|
||||||
work: Work::GossipAggregate {
|
work: Work::GossipAggregate {
|
||||||
aggregate: GossipAggregatePackage {
|
aggregate: Box::new(GossipAggregatePackage {
|
||||||
message_id,
|
message_id,
|
||||||
peer_id,
|
peer_id,
|
||||||
aggregate: Box::new(aggregate),
|
aggregate: Box::new(aggregate),
|
||||||
beacon_block_root,
|
beacon_block_root,
|
||||||
seen_timestamp,
|
seen_timestamp,
|
||||||
},
|
}),
|
||||||
process_individual: Box::new(process_individual),
|
process_individual: Box::new(process_individual),
|
||||||
process_batch: Box::new(process_batch),
|
process_batch: Box::new(process_batch),
|
||||||
},
|
},
|
||||||
@@ -508,20 +508,16 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
|
|||||||
request: BlocksByRangeRequest,
|
request: BlocksByRangeRequest,
|
||||||
) -> Result<(), Error<T::EthSpec>> {
|
) -> Result<(), Error<T::EthSpec>> {
|
||||||
let processor = self.clone();
|
let processor = self.clone();
|
||||||
let process_fn = move |send_idle_on_drop| {
|
let process_fn = async move {
|
||||||
let executor = processor.executor.clone();
|
let executor = processor.executor.clone();
|
||||||
processor.handle_blocks_by_range_request(
|
processor
|
||||||
executor,
|
.handle_blocks_by_range_request(executor, peer_id, request_id, request)
|
||||||
send_idle_on_drop,
|
.await;
|
||||||
peer_id,
|
|
||||||
request_id,
|
|
||||||
request,
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.try_send(BeaconWorkEvent {
|
self.try_send(BeaconWorkEvent {
|
||||||
drop_during_sync: false,
|
drop_during_sync: false,
|
||||||
work: Work::BlocksByRangeRequest(Box::new(process_fn)),
|
work: Work::BlocksByRangeRequest(Box::pin(process_fn)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -533,20 +529,16 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
|
|||||||
request: BlocksByRootRequest,
|
request: BlocksByRootRequest,
|
||||||
) -> Result<(), Error<T::EthSpec>> {
|
) -> Result<(), Error<T::EthSpec>> {
|
||||||
let processor = self.clone();
|
let processor = self.clone();
|
||||||
let process_fn = move |send_idle_on_drop| {
|
let process_fn = async move {
|
||||||
let executor = processor.executor.clone();
|
let executor = processor.executor.clone();
|
||||||
processor.handle_blocks_by_root_request(
|
processor
|
||||||
executor,
|
.handle_blocks_by_root_request(executor, peer_id, request_id, request)
|
||||||
send_idle_on_drop,
|
.await;
|
||||||
peer_id,
|
|
||||||
request_id,
|
|
||||||
request,
|
|
||||||
)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
self.try_send(BeaconWorkEvent {
|
self.try_send(BeaconWorkEvent {
|
||||||
drop_during_sync: false,
|
drop_during_sync: false,
|
||||||
work: Work::BlocksByRootsRequest(Box::new(process_fn)),
|
work: Work::BlocksByRootsRequest(Box::pin(process_fn)),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ use crate::service::NetworkMessage;
|
|||||||
use crate::status::ToStatusMessage;
|
use crate::status::ToStatusMessage;
|
||||||
use crate::sync::SyncMessage;
|
use crate::sync::SyncMessage;
|
||||||
use beacon_chain::{BeaconChainError, BeaconChainTypes, HistoricalBlockError, WhenSlotSkipped};
|
use beacon_chain::{BeaconChainError, BeaconChainTypes, HistoricalBlockError, WhenSlotSkipped};
|
||||||
use beacon_processor::SendOnDrop;
|
|
||||||
use itertools::process_results;
|
use itertools::process_results;
|
||||||
use lighthouse_network::rpc::methods::{BlobsByRangeRequest, BlobsByRootRequest};
|
use lighthouse_network::rpc::methods::{BlobsByRangeRequest, BlobsByRootRequest};
|
||||||
use lighthouse_network::rpc::*;
|
use lighthouse_network::rpc::*;
|
||||||
@@ -128,10 +127,9 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Handle a `BlocksByRoot` request from the peer.
|
/// Handle a `BlocksByRoot` request from the peer.
|
||||||
pub fn handle_blocks_by_root_request(
|
pub async fn handle_blocks_by_root_request(
|
||||||
self: Arc<Self>,
|
self: Arc<Self>,
|
||||||
executor: TaskExecutor,
|
executor: TaskExecutor,
|
||||||
send_on_drop: SendOnDrop,
|
|
||||||
peer_id: PeerId,
|
peer_id: PeerId,
|
||||||
request_id: PeerRequestId,
|
request_id: PeerRequestId,
|
||||||
request: BlocksByRootRequest,
|
request: BlocksByRootRequest,
|
||||||
@@ -145,10 +143,7 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
|
|||||||
Err(e) => return error!(self.log, "Error getting block stream"; "error" => ?e),
|
Err(e) => return error!(self.log, "Error getting block stream"; "error" => ?e),
|
||||||
};
|
};
|
||||||
// Fetching blocks is async because it may have to hit the execution layer for payloads.
|
// Fetching blocks is async because it may have to hit the execution layer for payloads.
|
||||||
executor.spawn(
|
|
||||||
async move {
|
|
||||||
let mut send_block_count = 0;
|
let mut send_block_count = 0;
|
||||||
let mut send_response = true;
|
|
||||||
while let Some((root, result)) = block_stream.next().await {
|
while let Some((root, result)) = block_stream.next().await {
|
||||||
match result.as_ref() {
|
match result.as_ref() {
|
||||||
Ok(Some(block)) => {
|
Ok(Some(block)) => {
|
||||||
@@ -175,14 +170,12 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
|
|||||||
"reason" => "execution layer not synced",
|
"reason" => "execution layer not synced",
|
||||||
);
|
);
|
||||||
// send the stream terminator
|
// send the stream terminator
|
||||||
self.send_error_response(
|
return self.send_error_response(
|
||||||
peer_id,
|
peer_id,
|
||||||
RPCResponseErrorCode::ResourceUnavailable,
|
RPCResponseErrorCode::ResourceUnavailable,
|
||||||
"Execution layer not synced".into(),
|
"Execution layer not synced".into(),
|
||||||
request_id,
|
request_id,
|
||||||
);
|
);
|
||||||
send_response = false;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
debug!(
|
debug!(
|
||||||
@@ -204,14 +197,8 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// send stream termination
|
// send stream termination
|
||||||
if send_response {
|
|
||||||
self.send_response(peer_id, Response::BlocksByRoot(None), request_id);
|
self.send_response(peer_id, Response::BlocksByRoot(None), request_id);
|
||||||
}
|
}
|
||||||
drop(send_on_drop);
|
|
||||||
},
|
|
||||||
"load_blocks_by_root_blocks",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Handle a `BlobsByRoot` request from the peer.
|
/// Handle a `BlobsByRoot` request from the peer.
|
||||||
pub fn handle_blobs_by_root_request(
|
pub fn handle_blobs_by_root_request(
|
||||||
@@ -386,10 +373,9 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Handle a `BlocksByRange` request from the peer.
|
/// Handle a `BlocksByRange` request from the peer.
|
||||||
pub fn handle_blocks_by_range_request(
|
pub async fn handle_blocks_by_range_request(
|
||||||
self: Arc<Self>,
|
self: Arc<Self>,
|
||||||
executor: TaskExecutor,
|
executor: TaskExecutor,
|
||||||
send_on_drop: SendOnDrop,
|
|
||||||
peer_id: PeerId,
|
peer_id: PeerId,
|
||||||
request_id: PeerRequestId,
|
request_id: PeerRequestId,
|
||||||
req: BlocksByRangeRequest,
|
req: BlocksByRangeRequest,
|
||||||
@@ -499,10 +485,7 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Fetching blocks is async because it may have to hit the execution layer for payloads.
|
// Fetching blocks is async because it may have to hit the execution layer for payloads.
|
||||||
executor.spawn(
|
|
||||||
async move {
|
|
||||||
let mut blocks_sent = 0;
|
let mut blocks_sent = 0;
|
||||||
let mut send_response = true;
|
|
||||||
|
|
||||||
while let Some((root, result)) = block_stream.next().await {
|
while let Some((root, result)) = block_stream.next().await {
|
||||||
match result.as_ref() {
|
match result.as_ref() {
|
||||||
@@ -528,14 +511,12 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
|
|||||||
"peer" => %peer_id,
|
"peer" => %peer_id,
|
||||||
"request_root" => ?root
|
"request_root" => ?root
|
||||||
);
|
);
|
||||||
self.send_error_response(
|
return self.send_error_response(
|
||||||
peer_id,
|
peer_id,
|
||||||
RPCResponseErrorCode::ServerError,
|
RPCResponseErrorCode::ServerError,
|
||||||
"Database inconsistency".into(),
|
"Database inconsistency".into(),
|
||||||
request_id,
|
request_id,
|
||||||
);
|
);
|
||||||
send_response = false;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
Err(BeaconChainError::BlockHashMissingFromExecutionLayer(_)) => {
|
Err(BeaconChainError::BlockHashMissingFromExecutionLayer(_)) => {
|
||||||
debug!(
|
debug!(
|
||||||
@@ -545,14 +526,12 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
|
|||||||
"reason" => "execution layer not synced",
|
"reason" => "execution layer not synced",
|
||||||
);
|
);
|
||||||
// send the stream terminator
|
// send the stream terminator
|
||||||
self.send_error_response(
|
return self.send_error_response(
|
||||||
peer_id,
|
peer_id,
|
||||||
RPCResponseErrorCode::ResourceUnavailable,
|
RPCResponseErrorCode::ResourceUnavailable,
|
||||||
"Execution layer not synced".into(),
|
"Execution layer not synced".into(),
|
||||||
request_id,
|
request_id,
|
||||||
);
|
);
|
||||||
send_response = false;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
if matches!(
|
if matches!(
|
||||||
@@ -577,14 +556,12 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// send the stream terminator
|
// send the stream terminator
|
||||||
self.send_error_response(
|
return self.send_error_response(
|
||||||
peer_id,
|
peer_id,
|
||||||
RPCResponseErrorCode::ServerError,
|
RPCResponseErrorCode::ServerError,
|
||||||
"Failed fetching blocks".into(),
|
"Failed fetching blocks".into(),
|
||||||
request_id,
|
request_id,
|
||||||
);
|
);
|
||||||
send_response = false;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -617,7 +594,6 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if send_response {
|
|
||||||
// send the stream terminator
|
// send the stream terminator
|
||||||
self.send_network_message(NetworkMessage::SendResponse {
|
self.send_network_message(NetworkMessage::SendResponse {
|
||||||
peer_id,
|
peer_id,
|
||||||
@@ -626,12 +602,6 @@ impl<T: BeaconChainTypes> NetworkBeaconProcessor<T> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
drop(send_on_drop);
|
|
||||||
},
|
|
||||||
"load_blocks_by_range_blocks",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Handle a `BlobsByRange` request from the peer.
|
/// Handle a `BlobsByRange` request from the peer.
|
||||||
pub fn handle_blobs_by_range_request(
|
pub fn handle_blobs_by_range_request(
|
||||||
self: Arc<Self>,
|
self: Arc<Self>,
|
||||||
|
|||||||
Reference in New Issue
Block a user