remove bounds from trait definitions (#16)
This commit is contained in:
parent
cc2d562d38
commit
6d12e83c35
|
@ -70,7 +70,10 @@ impl OverwatchHandle {
|
|||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
pub async fn update_settings<S: Services>(&self, settings: S::Settings) {
|
||||
pub async fn update_settings<S: Services>(&self, settings: S::Settings)
|
||||
where
|
||||
S::Settings: Send,
|
||||
{
|
||||
if let Err(e) = self
|
||||
.sender
|
||||
.send(OverwatchCommand::Settings(SettingsCommand(Box::new(
|
||||
|
|
|
@ -55,15 +55,15 @@ impl From<super::DynError> for Error {
|
|||
type FinishOverwatchSignal = ();
|
||||
|
||||
/// Marker trait for settings related elements
|
||||
pub type AnySettings = Box<dyn Any + Send + 'static>;
|
||||
pub type AnySettings = Box<dyn Any + Send>;
|
||||
|
||||
/// An overwatch run anything that implements this trait
|
||||
/// An implementor of this trait would have to handle the inner [`ServiceCore`](crate::services::ServiceCore)
|
||||
#[async_trait]
|
||||
pub trait Services: Sized + Send + Sync {
|
||||
pub trait Services: Sized {
|
||||
/// Inner [`ServiceCore::Settings`](crate::services::ServiceCore) grouping type.
|
||||
/// Normally this will be a settings object that group all the inner services settings.
|
||||
type Settings: Debug + Send + 'static;
|
||||
type Settings: Debug + 'static; // 'static is required for cast to `AnySetting`
|
||||
|
||||
/// Spawn a new instance of the Services object
|
||||
/// It returns a `(ServiceId, Runtime)` where Runtime is the `tokio::runtime::Runtime` attached for each
|
||||
|
@ -108,7 +108,7 @@ pub const OVERWATCH_THREAD_NAME: &str = "Overwatch";
|
|||
|
||||
impl<S> OverwatchRunner<S>
|
||||
where
|
||||
S: Services + 'static,
|
||||
S: Services + Send + 'static,
|
||||
{
|
||||
/// Start the Overwatch runner process
|
||||
/// It creates the `tokio::runtime::Runtime`, initialize the [`Services`] and start listening for
|
||||
|
|
|
@ -115,7 +115,12 @@ impl<S: ServiceCore> ServiceStateHandle<S> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<S: ServiceCore> ServiceRunner<S> {
|
||||
impl<S> ServiceRunner<S>
|
||||
where
|
||||
S::State: Send + Sync + 'static,
|
||||
S::StateOperator: Send + 'static,
|
||||
S: ServiceCore + 'static,
|
||||
{
|
||||
/// Spawn the service main loop and handle it lifecycle
|
||||
/// Return a handle to abort execution manually
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ pub trait ServiceData {
|
|||
|
||||
/// Main trait for Services initialization and main loop hook
|
||||
#[async_trait]
|
||||
pub trait ServiceCore: ServiceData + Send + Sized + 'static {
|
||||
pub trait ServiceCore: Sized + ServiceData {
|
||||
/// Initialize the service with the given state
|
||||
fn init(service_state: ServiceStateHandle<Self>) -> Result<Self, super::DynError>;
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ use tracing::error;
|
|||
/// It defines what is needed for a service state to be initialized.
|
||||
/// Need what set of settings information is required for it to be initialized [`ServiceState::Settings`]
|
||||
/// which usually is bound to the service itself [`crate::services::ServiceData::Settings`]
|
||||
pub trait ServiceState: Sized + Send + Sync + 'static {
|
||||
pub trait ServiceState: Sized {
|
||||
/// Settings object that the state can be initialized from
|
||||
type Settings;
|
||||
/// Errors that can occur during state initialization
|
||||
|
@ -27,7 +27,7 @@ pub trait ServiceState: Sized + Send + Sync + 'static {
|
|||
/// A state operator is an entity that can handle a state in a point of time
|
||||
/// to perform any operation based on it.
|
||||
#[async_trait]
|
||||
pub trait StateOperator: Send {
|
||||
pub trait StateOperator {
|
||||
/// The type of state that the operator can handle
|
||||
type StateInput: ServiceState;
|
||||
/// Operator initialization method. Can be implemented over some subset of settings
|
||||
|
@ -38,7 +38,13 @@ pub trait StateOperator: Send {
|
|||
|
||||
/// Operator that doesn't perform any operation upon state update
|
||||
#[derive(Copy)]
|
||||
pub struct NoOperator<StateInput>(PhantomData<StateInput>);
|
||||
pub struct NoOperator<StateInput>(PhantomData<*const StateInput>);
|
||||
|
||||
// NoOperator does not actually hold anything and is thus Sync.
|
||||
// Note that we don't use PhantomData<StateInput> as that would
|
||||
// suggest we indeed hold an instance of StateInput, see
|
||||
// https://doc.rust-lang.org/std/marker/struct.PhantomData.html#ownership-and-the-drop-check
|
||||
unsafe impl<T> Send for NoOperator<T> {}
|
||||
|
||||
// auto derive introduces unnecessary Clone bound on T
|
||||
impl<T> Clone for NoOperator<T> {
|
||||
|
@ -48,7 +54,7 @@ impl<T> Clone for NoOperator<T> {
|
|||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<StateInput: ServiceState> StateOperator for NoOperator<StateInput> {
|
||||
impl<StateInput: ServiceState + Send> StateOperator for NoOperator<StateInput> {
|
||||
type StateInput = StateInput;
|
||||
|
||||
fn from_settings<Settings>(_settings: Settings) -> Self {
|
||||
|
@ -69,7 +75,7 @@ impl<T> Clone for NoState<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<Settings: Send + Sync + 'static> ServiceState for NoState<Settings> {
|
||||
impl<Settings> ServiceState for NoState<Settings> {
|
||||
type Settings = Settings;
|
||||
|
||||
type Error = crate::DynError;
|
||||
|
@ -82,15 +88,15 @@ impl<Settings: Send + Sync + 'static> ServiceState for NoState<Settings> {
|
|||
/// Receiver part of the state handling mechanism.
|
||||
/// A state handle watches a stream of incoming states and triggers the attached operator handling
|
||||
/// method over it.
|
||||
pub struct StateHandle<S: ServiceState, Operator: StateOperator<StateInput = S>> {
|
||||
pub struct StateHandle<S, Operator> {
|
||||
watcher: StateWatcher<S>,
|
||||
operator: Operator,
|
||||
}
|
||||
|
||||
// auto derive introduces unnecessary Clone bound on T
|
||||
impl<S: ServiceState, Operator: StateOperator<StateInput = S>> Clone for StateHandle<S, Operator>
|
||||
impl<S, O> Clone for StateHandle<S, O>
|
||||
where
|
||||
Operator: Clone,
|
||||
O: Clone,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
|
@ -159,12 +165,8 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<S, Operator> StateHandle<S, Operator>
|
||||
where
|
||||
S: ServiceState + Clone,
|
||||
Operator: StateOperator<StateInput = S>,
|
||||
{
|
||||
pub fn new(initial_state: S, operator: Operator) -> (Self, StateUpdater<S>) {
|
||||
impl<S, O> StateHandle<S, O> {
|
||||
pub fn new(initial_state: S, operator: O) -> (Self, StateUpdater<S>) {
|
||||
let (sender, receiver) = channel(initial_state);
|
||||
let watcher = StateWatcher { receiver };
|
||||
let updater = StateUpdater {
|
||||
|
@ -173,7 +175,13 @@ where
|
|||
|
||||
(Self { watcher, operator }, updater)
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, Operator> StateHandle<S, Operator>
|
||||
where
|
||||
S: ServiceState + Clone + Send + Sync + 'static,
|
||||
Operator: StateOperator<StateInput = S>,
|
||||
{
|
||||
/// Wait for new state updates and run the operator handling method
|
||||
pub async fn run(self) {
|
||||
let Self {
|
||||
|
|
Loading…
Reference in New Issue