-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow subsystems using priority channels #77
Changes from all commits
dd5b7e2
e967098
007d630
ca3da68
722b8d2
e75c50f
877678b
89a5335
4b155f7
e0b1975
2d4e4e7
c172ccc
51134cc
7a99a08
a769a0e
03fae37
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -77,18 +77,27 @@ pub(crate) fn impl_channels_out_struct(info: &OrchestraInfo) -> Result<proc_macr | |
// when no defined messages in enum | ||
impl ChannelsOut { | ||
/// Send a message via a bounded channel. | ||
pub async fn send_and_log_error( | ||
pub async fn send_and_log_error<P: Priority>( | ||
&mut self, | ||
signals_received: usize, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd like to see a unit test regarding how There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added signals to tests |
||
message: #message_wrapper, | ||
message: #message_wrapper | ||
) { | ||
let res: ::std::result::Result<_, _> = match message { | ||
#( | ||
#feature_gates | ||
#message_wrapper :: #consumes_variant ( inner ) => { | ||
self. #channel_name .send( | ||
#support_crate ::make_packet(signals_received, #maybe_boxed_send) | ||
).await.map_err(|_| stringify!( #channel_name )) | ||
match P::priority() { | ||
PriorityLevel::Normal => { | ||
self. #channel_name .send( | ||
#support_crate ::make_packet(signals_received, #maybe_boxed_send) | ||
).await | ||
}, | ||
PriorityLevel::High => { | ||
self. #channel_name .priority_send( | ||
#support_crate ::make_packet(signals_received, #maybe_boxed_send) | ||
).await | ||
}, | ||
}.map_err(|_| stringify!( #channel_name )) | ||
} | ||
)* | ||
// subsystems that are wip | ||
|
@@ -116,7 +125,7 @@ pub(crate) fn impl_channels_out_struct(info: &OrchestraInfo) -> Result<proc_macr | |
} | ||
|
||
/// Try to send a message via a bounded channel. | ||
pub fn try_send( | ||
pub fn try_send<P: Priority>( | ||
&mut self, | ||
signals_received: usize, | ||
message: #message_wrapper, | ||
|
@@ -125,9 +134,18 @@ pub(crate) fn impl_channels_out_struct(info: &OrchestraInfo) -> Result<proc_macr | |
#( | ||
#feature_gates | ||
#message_wrapper :: #consumes_variant ( inner ) => { | ||
self. #channel_name .try_send( | ||
#support_crate ::make_packet(signals_received, #maybe_boxed_send) | ||
).map_err(|err| match err { | ||
match P::priority() { | ||
PriorityLevel::Normal => { | ||
self. #channel_name .try_send( | ||
#support_crate ::make_packet(signals_received, #maybe_boxed_send) | ||
) | ||
}, | ||
PriorityLevel::High => { | ||
self. #channel_name .try_priority_send( | ||
#support_crate ::make_packet(signals_received, #maybe_boxed_send) | ||
) | ||
}, | ||
}.map_err(|err| match err { | ||
#support_crate ::metered::TrySendError::Full(err_inner) => #support_crate ::metered::TrySendError::Full(#message_wrapper:: #consumes_variant ( #maybe_unbox_error )), | ||
#support_crate ::metered::TrySendError::Closed(err_inner) => #support_crate ::metered::TrySendError::Closed(#message_wrapper:: #consumes_variant ( #maybe_unbox_error )), | ||
}) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -494,6 +494,37 @@ where | |
fn start(self, ctx: Ctx) -> SpawnedSubsystem<E>; | ||
} | ||
|
||
/// Priority of messages sending to the individual subsystems. | ||
/// Only for the bounded channel sender. | ||
pub enum PriorityLevel { | ||
/// Normal priority. | ||
Normal, | ||
/// High priority. | ||
High, | ||
} | ||
/// Normal priority. | ||
pub struct NormalPriority; | ||
/// High priority. | ||
pub struct HighPriority; | ||
|
||
/// Describes the priority of the message. | ||
pub trait Priority { | ||
/// The priority level. | ||
fn priority() -> PriorityLevel { | ||
PriorityLevel::Normal | ||
} | ||
} | ||
impl Priority for NormalPriority { | ||
fn priority() -> PriorityLevel { | ||
PriorityLevel::Normal | ||
} | ||
} | ||
impl Priority for HighPriority { | ||
fn priority() -> PriorityLevel { | ||
PriorityLevel::High | ||
} | ||
} | ||
|
||
/// Sender end of a channel to interface with a subsystem. | ||
#[async_trait::async_trait] | ||
pub trait SubsystemSender<OutgoingMessage>: Clone + Send + 'static | ||
|
@@ -503,6 +534,9 @@ where | |
/// Send a direct message to some other `Subsystem`, routed based on message type. | ||
async fn send_message(&mut self, msg: OutgoingMessage); | ||
|
||
/// Send a direct message with defined priority to some other `Subsystem`, routed based on message type. | ||
async fn send_message_with_priority<P: Priority>(&mut self, msg: OutgoingMessage); | ||
|
||
/// Tries to send a direct message to some other `Subsystem`, routed based on message type. | ||
/// This method is useful for cases where the message queue is bounded and the message is ok | ||
/// to be dropped if the queue is full. If the queue is full, this method will return an error. | ||
|
@@ -512,6 +546,14 @@ where | |
msg: OutgoingMessage, | ||
) -> Result<(), metered::TrySendError<OutgoingMessage>>; | ||
|
||
/// Tries to send a direct message with defined priority to some other `Subsystem`, routed based on message type. | ||
/// If the queue is full, this method will return an error. | ||
/// This method is not async and will not block the current task. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It doesn't make much sense to drop priority messages. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Make sense. Does it mean that we should not have the try_priority_send at all? |
||
fn try_send_message_with_priority<P: Priority>( | ||
&mut self, | ||
msg: OutgoingMessage, | ||
) -> Result<(), metered::TrySendError<OutgoingMessage>>; | ||
|
||
/// Send multiple direct messages to other `Subsystem`s, routed based on message type. | ||
async fn send_messages<I>(&mut self, msgs: I) | ||
where | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Should we make this configurable per-subsystem ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can, but I think we'll have little to gain considering the number of subsystems.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At least from Polkadot perspective, we only need the priority channels for the networking subsystems, so it makes sense to have it configurable per subsystem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd be in favor of having it per subsystem or for everything. We will poll twice as many channels, in the empty priority channel case, which will be the default for most I presume.