mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 21:01:02 +00:00
feat/overseer: introduce closure init (#3775)
* feat/overseer: introduce closure init Enables removal of the connected/disconnected overseer state. * feat/overseer: allow replacement logic to access the original Allows to re-use init-once types, which would otherwise error. * feat/overseer: introduce external connector Preparation for removal of `AllSubsystems` which is another prerequisite for removing the connect/disconnect state. * fix/test: replace needs closure * fixup * simplify * mea culpa * all-subsystems-gen test
This commit is contained in:
committed by
GitHub
parent
5596170bfb
commit
3cc5a1eee9
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use quote::quote;
|
||||
use quote::{format_ident, quote};
|
||||
use syn::Ident;
|
||||
|
||||
use super::*;
|
||||
@@ -27,8 +27,14 @@ pub(crate) fn impl_builder(info: &OverseerInfo) -> proc_macro2::TokenStream {
|
||||
let overseer_name = info.overseer_name.clone();
|
||||
let builder = Ident::new(&(overseer_name.to_string() + "Builder"), overseer_name.span());
|
||||
let handle = Ident::new(&(overseer_name.to_string() + "Handle"), overseer_name.span());
|
||||
let connector = Ident::new(&(overseer_name.to_string() + "Connector"), overseer_name.span());
|
||||
|
||||
let subsystem_name = &info.subsystem_names_without_wip();
|
||||
let subsystem_name_init_with = &info
|
||||
.subsystem_names_without_wip()
|
||||
.iter()
|
||||
.map(|subsystem_name| format_ident!("{}_with", subsystem_name))
|
||||
.collect::<Vec<_>>();
|
||||
let builder_generic_ty = &info.builder_generic_types();
|
||||
|
||||
let channel_name = &info.channel_names_without_wip("");
|
||||
@@ -106,10 +112,65 @@ pub(crate) fn impl_builder(info: &OverseerInfo) -> proc_macro2::TokenStream {
|
||||
/// Handle for an overseer.
|
||||
pub type #handle = #support_crate ::metered::MeteredSender< #event >;
|
||||
|
||||
/// External connector.
|
||||
pub struct #connector {
|
||||
/// Publicly accessible handle, to be used for setting up
|
||||
/// components that are _not_ subsystems but access is needed
|
||||
/// due to other limitations.
|
||||
///
|
||||
/// For subsystems, use the `_with` variants of the builder.
|
||||
handle: #handle,
|
||||
/// The side consumed by the `spawned` side of the overseer pattern.
|
||||
consumer: #support_crate ::metered::MeteredReceiver < #event >,
|
||||
}
|
||||
|
||||
impl #connector {
|
||||
/// Obtain access to the overseer handle.
|
||||
pub fn as_handle_mut(&mut self) -> &mut #handle {
|
||||
&mut self.handle
|
||||
}
|
||||
/// Obtain access to the overseer handle.
|
||||
pub fn as_handle(&mut self) -> &#handle {
|
||||
&self.handle
|
||||
}
|
||||
}
|
||||
|
||||
impl ::std::default::Default for #connector {
|
||||
fn default() -> Self {
|
||||
let (events_tx, events_rx) = #support_crate ::metered::channel::<
|
||||
#event
|
||||
>(SIGNAL_CHANNEL_CAPACITY);
|
||||
|
||||
Self {
|
||||
handle: events_tx,
|
||||
consumer: events_rx,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Convenience alias.
|
||||
type SubsystemInitFn<T> = Box<dyn FnOnce(#handle) -> ::std::result::Result<T, #error_ty> >;
|
||||
|
||||
/// Init kind of a field of the overseer.
|
||||
enum FieldInitMethod<T> {
|
||||
/// Defer initialization to a point where the `handle` is available.
|
||||
Fn(SubsystemInitFn<T>),
|
||||
/// Directly initialize the subsystem with the given subsystem type `T`.
|
||||
Value(T),
|
||||
/// Subsystem field does not have value just yet.
|
||||
Uninitialized
|
||||
}
|
||||
|
||||
impl<T> ::std::default::Default for FieldInitMethod<T> {
|
||||
fn default() -> Self {
|
||||
Self::Uninitialized
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(missing_docs)]
|
||||
pub struct #builder #builder_generics {
|
||||
#(
|
||||
#subsystem_name : ::std::option::Option< #builder_generic_ty >,
|
||||
#subsystem_name : FieldInitMethod< #builder_generic_ty >,
|
||||
)*
|
||||
#(
|
||||
#baggage_name : ::std::option::Option< #baggage_ty >,
|
||||
@@ -129,7 +190,7 @@ pub(crate) fn impl_builder(info: &OverseerInfo) -> proc_macro2::TokenStream {
|
||||
|
||||
Self {
|
||||
#(
|
||||
#subsystem_name: None,
|
||||
#subsystem_name: Default::default(),
|
||||
)*
|
||||
#(
|
||||
#baggage_name: None,
|
||||
@@ -152,7 +213,18 @@ pub(crate) fn impl_builder(info: &OverseerInfo) -> proc_macro2::TokenStream {
|
||||
#(
|
||||
/// Specify the particular subsystem implementation.
|
||||
pub fn #subsystem_name (mut self, subsystem: #builder_generic_ty ) -> Self {
|
||||
self. #subsystem_name = Some( subsystem );
|
||||
self. #subsystem_name = FieldInitMethod::Value( subsystem );
|
||||
self
|
||||
}
|
||||
|
||||
/// Specify the particular subsystem by giving a init function.
|
||||
pub fn #subsystem_name_init_with <'a, F> (mut self, subsystem_init_fn: F ) -> Self
|
||||
where
|
||||
F: 'static + FnOnce(#handle) -> ::std::result::Result<#builder_generic_ty, #error_ty>,
|
||||
{
|
||||
self. #subsystem_name = FieldInitMethod::Fn(
|
||||
Box::new(subsystem_init_fn) as SubsystemInitFn<#builder_generic_ty>
|
||||
);
|
||||
self
|
||||
}
|
||||
)*
|
||||
@@ -166,13 +238,20 @@ pub(crate) fn impl_builder(info: &OverseerInfo) -> proc_macro2::TokenStream {
|
||||
)*
|
||||
|
||||
/// Complete the construction and create the overseer type.
|
||||
pub fn build(mut self) -> ::std::result::Result<(#overseer_name #generics, #handle), #error_ty>
|
||||
{
|
||||
let (events_tx, events_rx) = #support_crate ::metered::channel::<
|
||||
#event
|
||||
>(SIGNAL_CHANNEL_CAPACITY);
|
||||
pub fn build(mut self) -> ::std::result::Result<(#overseer_name #generics, #handle), #error_ty> {
|
||||
let connector = #connector ::default();
|
||||
self.build_with_connector(connector)
|
||||
}
|
||||
|
||||
let handle: #handle = events_tx.clone();
|
||||
/// Complete the construction and create the overseer type based on an existing `connector`.
|
||||
pub fn build_with_connector(mut self, connector: #connector) -> ::std::result::Result<(#overseer_name #generics, #handle), #error_ty>
|
||||
{
|
||||
let #connector {
|
||||
handle: events_tx,
|
||||
consumer: events_rx,
|
||||
} = connector;
|
||||
|
||||
let handle = events_tx.clone();
|
||||
|
||||
let (to_overseer_tx, to_overseer_rx) = #support_crate ::metered::unbounded::<
|
||||
ToOverseer
|
||||
@@ -212,7 +291,12 @@ pub(crate) fn impl_builder(info: &OverseerInfo) -> proc_macro2::TokenStream {
|
||||
#(
|
||||
// TODO generate a builder pattern that ensures this
|
||||
// TODO https://github.com/paritytech/polkadot/issues/3427
|
||||
let #subsystem_name = self. #subsystem_name .expect("All subsystem must exist with the builder pattern.");
|
||||
let #subsystem_name = match self. #subsystem_name {
|
||||
FieldInitMethod::Fn(func) => func(handle.clone())?,
|
||||
FieldInitMethod::Value(val) => val,
|
||||
FieldInitMethod::Uninitialized =>
|
||||
panic!("All subsystems must exist with the builder pattern."),
|
||||
};
|
||||
|
||||
let unbounded_meter = #channel_name_unbounded_rx.meter().clone();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user