mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 10:31:03 +00:00
Simplify subsystem jobs (#2037)
* Simplify subsystem jobs This pr simplifies the subsystem jobs interface. Instead of requiring an extra message that is used to signal that a job should be ended, a job now ends when the receiver returns `None`. Besides that it changes the interface to enforce that messages to a job provide a relay parent. * Drop ToJobTrait * Remove FromJob We always convert this message to FromJobCommand anyway.
This commit is contained in:
@@ -30,86 +30,21 @@ use polkadot_node_subsystem::{
|
||||
},
|
||||
};
|
||||
use polkadot_node_subsystem_util::{
|
||||
self as util, delegated_subsystem, JobTrait, ToJobTrait, FromJobCommand,
|
||||
metrics::{self, prometheus},
|
||||
self as util, delegated_subsystem, JobTrait, FromJobCommand, metrics::{self, prometheus},
|
||||
};
|
||||
use polkadot_primitives::v1::{CandidateReceipt, CollatorId, Hash, Id as ParaId, PoV};
|
||||
use std::{convert::TryFrom, pin::Pin};
|
||||
use std::pin::Pin;
|
||||
use thiserror::Error;
|
||||
|
||||
const LOG_TARGET: &'static str = "candidate_selection";
|
||||
|
||||
struct CandidateSelectionJob {
|
||||
sender: mpsc::Sender<FromJob>,
|
||||
receiver: mpsc::Receiver<ToJob>,
|
||||
sender: mpsc::Sender<FromJobCommand>,
|
||||
receiver: mpsc::Receiver<CandidateSelectionMessage>,
|
||||
metrics: Metrics,
|
||||
seconded_candidate: Option<CollatorId>,
|
||||
}
|
||||
|
||||
/// This enum defines the messages that the provisioner is prepared to receive.
|
||||
#[derive(Debug)]
|
||||
pub enum ToJob {
|
||||
/// The provisioner message is the main input to the provisioner.
|
||||
CandidateSelection(CandidateSelectionMessage),
|
||||
/// This message indicates that the provisioner should shut itself down.
|
||||
Stop,
|
||||
}
|
||||
|
||||
impl ToJobTrait for ToJob {
|
||||
const STOP: Self = Self::Stop;
|
||||
|
||||
fn relay_parent(&self) -> Option<Hash> {
|
||||
match self {
|
||||
Self::CandidateSelection(csm) => csm.relay_parent(),
|
||||
Self::Stop => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<AllMessages> for ToJob {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(msg: AllMessages) -> Result<Self, Self::Error> {
|
||||
match msg {
|
||||
AllMessages::CandidateSelection(csm) => Ok(Self::CandidateSelection(csm)),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CandidateSelectionMessage> for ToJob {
|
||||
fn from(csm: CandidateSelectionMessage) -> Self {
|
||||
Self::CandidateSelection(csm)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
enum FromJob {
|
||||
Backing(CandidateBackingMessage),
|
||||
Collator(CollatorProtocolMessage),
|
||||
}
|
||||
|
||||
impl From<FromJob> for FromJobCommand {
|
||||
fn from(from_job: FromJob) -> FromJobCommand {
|
||||
FromJobCommand::SendMessage(match from_job {
|
||||
FromJob::Backing(msg) => AllMessages::CandidateBacking(msg),
|
||||
FromJob::Collator(msg) => AllMessages::CollatorProtocol(msg),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<AllMessages> for FromJob {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(msg: AllMessages) -> Result<Self, Self::Error> {
|
||||
match msg {
|
||||
AllMessages::CandidateBacking(msg) => Ok(FromJob::Backing(msg)),
|
||||
AllMessages::CollatorProtocol(msg) => Ok(FromJob::Collator(msg)),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
enum Error {
|
||||
#[error(transparent)]
|
||||
@@ -123,40 +58,32 @@ enum Error {
|
||||
}
|
||||
|
||||
impl JobTrait for CandidateSelectionJob {
|
||||
type ToJob = ToJob;
|
||||
type FromJob = FromJob;
|
||||
type ToJob = CandidateSelectionMessage;
|
||||
type Error = Error;
|
||||
type RunArgs = ();
|
||||
type Metrics = Metrics;
|
||||
|
||||
const NAME: &'static str = "CandidateSelectionJob";
|
||||
|
||||
/// Run a job for the parent block indicated
|
||||
//
|
||||
// this function is in charge of creating and executing the job's main loop
|
||||
#[tracing::instrument(skip(_relay_parent, _run_args, metrics, receiver, sender), fields(subsystem = LOG_TARGET))]
|
||||
fn run(
|
||||
_relay_parent: Hash,
|
||||
_run_args: Self::RunArgs,
|
||||
metrics: Self::Metrics,
|
||||
receiver: mpsc::Receiver<ToJob>,
|
||||
sender: mpsc::Sender<FromJob>,
|
||||
receiver: mpsc::Receiver<CandidateSelectionMessage>,
|
||||
sender: mpsc::Sender<FromJobCommand>,
|
||||
) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send>> {
|
||||
Box::pin(async move {
|
||||
let job = CandidateSelectionJob::new(metrics, sender, receiver);
|
||||
|
||||
// it isn't necessary to break run_loop into its own function,
|
||||
// but it's convenient to separate the concerns in this way
|
||||
job.run_loop().await
|
||||
})
|
||||
async move {
|
||||
CandidateSelectionJob::new(metrics, sender, receiver).run_loop().await
|
||||
}.boxed()
|
||||
}
|
||||
}
|
||||
|
||||
impl CandidateSelectionJob {
|
||||
pub fn new(
|
||||
metrics: Metrics,
|
||||
sender: mpsc::Sender<FromJob>,
|
||||
receiver: mpsc::Receiver<ToJob>,
|
||||
sender: mpsc::Sender<FromJobCommand>,
|
||||
receiver: mpsc::Receiver<CandidateSelectionMessage>,
|
||||
) -> Self {
|
||||
Self {
|
||||
sender,
|
||||
@@ -166,28 +93,23 @@ impl CandidateSelectionJob {
|
||||
}
|
||||
}
|
||||
|
||||
async fn run_loop(mut self) -> Result<(), Error> {
|
||||
self.run_loop_borrowed().await
|
||||
}
|
||||
|
||||
/// this function exists for testing and should not generally be used; use `run_loop` instead.
|
||||
async fn run_loop_borrowed(&mut self) -> Result<(), Error> {
|
||||
while let Some(msg) = self.receiver.next().await {
|
||||
match msg {
|
||||
ToJob::CandidateSelection(CandidateSelectionMessage::Collation(
|
||||
async fn run_loop(&mut self) -> Result<(), Error> {
|
||||
loop {
|
||||
match self.receiver.next().await {
|
||||
Some(CandidateSelectionMessage::Collation(
|
||||
relay_parent,
|
||||
para_id,
|
||||
collator_id,
|
||||
)) => {
|
||||
self.handle_collation(relay_parent, para_id, collator_id).await;
|
||||
}
|
||||
ToJob::CandidateSelection(CandidateSelectionMessage::Invalid(
|
||||
Some(CandidateSelectionMessage::Invalid(
|
||||
_,
|
||||
candidate_receipt,
|
||||
)) => {
|
||||
self.handle_invalid(candidate_receipt).await;
|
||||
}
|
||||
ToJob::Stop => break,
|
||||
None => break,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,16 +205,16 @@ async fn get_collation(
|
||||
relay_parent: Hash,
|
||||
para_id: ParaId,
|
||||
collator_id: CollatorId,
|
||||
mut sender: mpsc::Sender<FromJob>,
|
||||
mut sender: mpsc::Sender<FromJobCommand>,
|
||||
) -> Result<(CandidateReceipt, PoV), Error> {
|
||||
let (tx, rx) = oneshot::channel();
|
||||
sender
|
||||
.send(FromJob::Collator(CollatorProtocolMessage::FetchCollation(
|
||||
.send(AllMessages::from(CollatorProtocolMessage::FetchCollation(
|
||||
relay_parent,
|
||||
collator_id,
|
||||
para_id,
|
||||
tx,
|
||||
)))
|
||||
)).into())
|
||||
.await?;
|
||||
rx.await.map_err(Into::into)
|
||||
}
|
||||
@@ -301,15 +223,15 @@ async fn second_candidate(
|
||||
relay_parent: Hash,
|
||||
candidate_receipt: CandidateReceipt,
|
||||
pov: PoV,
|
||||
sender: &mut mpsc::Sender<FromJob>,
|
||||
sender: &mut mpsc::Sender<FromJobCommand>,
|
||||
metrics: &Metrics,
|
||||
) -> Result<(), Error> {
|
||||
match sender
|
||||
.send(FromJob::Backing(CandidateBackingMessage::Second(
|
||||
.send(AllMessages::from(CandidateBackingMessage::Second(
|
||||
relay_parent,
|
||||
candidate_receipt,
|
||||
pov,
|
||||
)))
|
||||
)).into())
|
||||
.await
|
||||
{
|
||||
Err(err) => {
|
||||
@@ -326,12 +248,12 @@ async fn second_candidate(
|
||||
|
||||
async fn forward_invalidity_note(
|
||||
received_from: &CollatorId,
|
||||
sender: &mut mpsc::Sender<FromJob>,
|
||||
sender: &mut mpsc::Sender<FromJobCommand>,
|
||||
) -> Result<(), Error> {
|
||||
sender
|
||||
.send(FromJob::Collator(CollatorProtocolMessage::ReportCollator(
|
||||
.send(AllMessages::from(CollatorProtocolMessage::ReportCollator(
|
||||
received_from.clone(),
|
||||
)))
|
||||
)).into())
|
||||
.await
|
||||
.map_err(Into::into)
|
||||
}
|
||||
@@ -420,7 +342,7 @@ impl metrics::Metrics for Metrics {
|
||||
}
|
||||
}
|
||||
|
||||
delegated_subsystem!(CandidateSelectionJob((), Metrics) <- ToJob as CandidateSelectionSubsystem);
|
||||
delegated_subsystem!(CandidateSelectionJob((), Metrics) <- CandidateSelectionMessage as CandidateSelectionSubsystem);
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
@@ -436,7 +358,7 @@ mod tests {
|
||||
postconditions: Postconditions,
|
||||
) where
|
||||
Preconditions: FnOnce(&mut CandidateSelectionJob),
|
||||
TestBuilder: FnOnce(mpsc::Sender<ToJob>, mpsc::Receiver<FromJob>) -> Test,
|
||||
TestBuilder: FnOnce(mpsc::Sender<CandidateSelectionMessage>, mpsc::Receiver<FromJobCommand>) -> Test,
|
||||
Test: Future<Output = ()>,
|
||||
Postconditions: FnOnce(CandidateSelectionJob, Result<(), Error>),
|
||||
{
|
||||
@@ -453,7 +375,7 @@ mod tests {
|
||||
|
||||
let (_, job_result) = futures::executor::block_on(future::join(
|
||||
test(to_job_tx, from_job_rx),
|
||||
job.run_loop_borrowed(),
|
||||
job.run_loop(),
|
||||
));
|
||||
|
||||
postconditions(job, job_result);
|
||||
@@ -479,12 +401,10 @@ mod tests {
|
||||
|_job| {},
|
||||
|mut to_job, mut from_job| async move {
|
||||
to_job
|
||||
.send(ToJob::CandidateSelection(
|
||||
CandidateSelectionMessage::Collation(
|
||||
relay_parent,
|
||||
para_id,
|
||||
collator_id_clone.clone(),
|
||||
),
|
||||
.send(CandidateSelectionMessage::Collation(
|
||||
relay_parent,
|
||||
para_id,
|
||||
collator_id_clone.clone(),
|
||||
))
|
||||
.await
|
||||
.unwrap();
|
||||
@@ -492,12 +412,12 @@ mod tests {
|
||||
|
||||
while let Some(msg) = from_job.next().await {
|
||||
match msg {
|
||||
FromJob::Collator(CollatorProtocolMessage::FetchCollation(
|
||||
FromJobCommand::SendMessage(AllMessages::CollatorProtocol(CollatorProtocolMessage::FetchCollation(
|
||||
got_relay_parent,
|
||||
collator_id,
|
||||
got_para_id,
|
||||
return_sender,
|
||||
)) => {
|
||||
))) => {
|
||||
assert_eq!(got_relay_parent, relay_parent);
|
||||
assert_eq!(got_para_id, para_id);
|
||||
assert_eq!(collator_id, collator_id_clone);
|
||||
@@ -506,11 +426,11 @@ mod tests {
|
||||
.send((candidate_receipt.clone(), pov.clone()))
|
||||
.unwrap();
|
||||
}
|
||||
FromJob::Backing(CandidateBackingMessage::Second(
|
||||
FromJobCommand::SendMessage(AllMessages::CandidateBacking(CandidateBackingMessage::Second(
|
||||
got_relay_parent,
|
||||
got_candidate_receipt,
|
||||
got_pov,
|
||||
)) => {
|
||||
))) => {
|
||||
assert_eq!(got_relay_parent, relay_parent);
|
||||
assert_eq!(got_candidate_receipt, candidate_receipt);
|
||||
assert_eq!(got_pov, pov);
|
||||
@@ -546,12 +466,10 @@ mod tests {
|
||||
|job| job.seconded_candidate = Some(prev_collator_id.clone()),
|
||||
|mut to_job, mut from_job| async move {
|
||||
to_job
|
||||
.send(ToJob::CandidateSelection(
|
||||
CandidateSelectionMessage::Collation(
|
||||
relay_parent,
|
||||
para_id,
|
||||
collator_id_clone,
|
||||
),
|
||||
.send(CandidateSelectionMessage::Collation(
|
||||
relay_parent,
|
||||
para_id,
|
||||
collator_id_clone,
|
||||
))
|
||||
.await
|
||||
.unwrap();
|
||||
@@ -559,11 +477,11 @@ mod tests {
|
||||
|
||||
while let Some(msg) = from_job.next().await {
|
||||
match msg {
|
||||
FromJob::Backing(CandidateBackingMessage::Second(
|
||||
FromJobCommand::SendMessage(AllMessages::CandidateBacking(CandidateBackingMessage::Second(
|
||||
_got_relay_parent,
|
||||
_got_candidate_receipt,
|
||||
_got_pov,
|
||||
)) => {
|
||||
))) => {
|
||||
*was_seconded_clone.lock().await = true;
|
||||
}
|
||||
other => panic!("unexpected message from job: {:?}", other),
|
||||
@@ -595,18 +513,16 @@ mod tests {
|
||||
|job| job.seconded_candidate = Some(collator_id.clone()),
|
||||
|mut to_job, mut from_job| async move {
|
||||
to_job
|
||||
.send(ToJob::CandidateSelection(
|
||||
CandidateSelectionMessage::Invalid(relay_parent, candidate_receipt),
|
||||
))
|
||||
.send(CandidateSelectionMessage::Invalid(relay_parent, candidate_receipt))
|
||||
.await
|
||||
.unwrap();
|
||||
std::mem::drop(to_job);
|
||||
|
||||
while let Some(msg) = from_job.next().await {
|
||||
match msg {
|
||||
FromJob::Collator(CollatorProtocolMessage::ReportCollator(
|
||||
FromJobCommand::SendMessage(AllMessages::CollatorProtocol(CollatorProtocolMessage::ReportCollator(
|
||||
got_collator_id,
|
||||
)) => {
|
||||
))) => {
|
||||
assert_eq!(got_collator_id, collator_id_clone);
|
||||
|
||||
*sent_report_clone.lock().await = true;
|
||||
|
||||
Reference in New Issue
Block a user