state service + supevisor prep

another-service-failure
Avril 4 years ago
parent 925770fbeb
commit 815feaa4a7
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -540,6 +540,7 @@ pub trait AnyCloneable: mopa::Any
{ {
fn clone_dyn(&self) -> Box<dyn AnyCloneable + Send + Sync + 'static>; fn clone_dyn(&self) -> Box<dyn AnyCloneable + Send + Sync + 'static>;
fn clone_dyn_any(&self) -> Box<dyn Any + Send + 'static>; fn clone_dyn_any(&self) -> Box<dyn Any + Send + 'static>;
fn clone_dyn_any_sync(&self) -> Box<dyn Any + Send + Sync + 'static>;
} }
mopafy!(AnyCloneable); mopafy!(AnyCloneable);
@ -551,6 +552,9 @@ impl<T: ?Sized + Clone + Any + Send + Sync + 'static> AnyCloneable for T
#[inline] fn clone_dyn_any(&self) -> Box<dyn Any + Send + 'static> { #[inline] fn clone_dyn_any(&self) -> Box<dyn Any + Send + 'static> {
Box::new(self.clone()) Box::new(self.clone())
} }
fn clone_dyn_any_sync(&self) -> Box<dyn Any + Send + Sync + 'static> {
Box::new(self.clone())
}
} }
/// A dynamically clonable heap allocated polymorphic `Any` object. /// A dynamically clonable heap allocated polymorphic `Any` object.
@ -580,6 +584,8 @@ impl Clone for DynCloneable
mod maybe_iter mod maybe_iter
{ {
use std::iter::{once, Once, Chain};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
enum Inner<I, T> enum Inner<I, T>
{ {
@ -598,7 +604,7 @@ mod maybe_iter
/// Create a single element iterator /// Create a single element iterator
pub fn one<U: Into<T>>(from: U) -> Self pub fn one<U: Into<T>>(from: U) -> Self
{ {
Self(Inner::One(std::iter::once(from.into()))) Self(Inner::One(once(from.into())))
} }
/// Create a new instance from an iterator /// Create a new instance from an iterator
pub fn many<U: IntoIterator<IntoIter = I, Item=T>>(from: U) -> Self pub fn many<U: IntoIterator<IntoIter = I, Item=T>>(from: U) -> Self
@ -610,8 +616,27 @@ mod maybe_iter
{ {
Self(Inner::None) Self(Inner::None)
} }
/// Create a new instance from an iterator.
///
/// # Not using `FromIterator`.
/// 0, 1, many.. will be respected, with no unneeded heap allocations. This is not currently possible with the `FromIterator` trait.
pub fn from_iter<I2: IntoIterator<Item = T>>(from: I2) -> MaybeIter<Chain<Chain<Once<T>, Once<T>>, I2::IntoIter>, T>
{
let mut iter = from.into_iter();
MaybeIter(match (iter.next(), iter.next()) {
(Some(first), None) => Inner::One(once(first)),
(Some(first), Some(second)) => {
Inner::Some(once(first)
.chain(once(second))
.chain(iter))
},
_ => Inner::None,
})
}
} }
impl<I, T, U> From<Option<U>> for MaybeIter<I, T> impl<I, T, U> From<Option<U>> for MaybeIter<I, T>
where I: Iterator<Item=T>, where I: Iterator<Item=T>,
U: IntoIterator<IntoIter=I, Item=T> U: IntoIterator<IntoIter=I, Item=T>
@ -649,6 +674,17 @@ mod maybe_iter
} }
} }
impl<T, I: Iterator<Item=T>> std::iter::DoubleEndedIterator for MaybeIter<I, T>
where I: std::iter::DoubleEndedIterator
{
fn next_back(&mut self) -> Option<Self::Item> {
match &mut self.0 {
Inner::Some(x) => x.next_back(),
Inner::One(x) => x.next_back(),
Inner::None => None,
}
}
}
impl<T, I: Iterator<Item=T>> std::iter::FusedIterator for MaybeIter<I, T> impl<T, I: Iterator<Item=T>> std::iter::FusedIterator for MaybeIter<I, T>
where I: std::iter::FusedIterator{} where I: std::iter::FusedIterator{}
impl<T, I: Iterator<Item=T>> ExactSizeIterator for MaybeIter<I, T> impl<T, I: Iterator<Item=T>> ExactSizeIterator for MaybeIter<I, T>

@ -10,7 +10,9 @@
#[macro_use] extern crate mopa; #[macro_use] extern crate mopa;
#[macro_use] extern crate cfg_if; #[macro_use] extern crate cfg_if;
#[allow(unused_imports)]
use std::convert::{TryFrom, TryInto}; use std::convert::{TryFrom, TryInto};
#[allow(unused_imports)]
use color_eyre::{ use color_eyre::{
eyre::{ eyre::{
WrapErr as _, WrapErr as _,

@ -19,6 +19,7 @@ use std::collections::{BTreeMap};
id_type!(ServiceSubID; "Optional ID for filtering directed broadcast messages"); id_type!(ServiceSubID; "Optional ID for filtering directed broadcast messages");
id_type!(BroadcastID; "Each broadcast message has a unique ID.");
/// Signal the shutdown method to the supervisor. /// Signal the shutdown method to the supervisor.
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)]
@ -82,11 +83,13 @@ pub(super) struct Supervisor
/// ///
/// These objects can be cloned and downcasted, becaause they are atomically refcounted if that is more desireable. /// These objects can be cloned and downcasted, becaause they are atomically refcounted if that is more desireable.
#[derive(Clone)] #[derive(Clone)]
#[repr(transparent)]
pub struct ServiceEventObject(Arc<dyn Any + Send + Sync + 'static>); pub struct ServiceEventObject(Arc<dyn Any + Send + Sync + 'static>);
shim_debug!(ServiceEventObject); shim_debug!(ServiceEventObject);
/// A weak reference to a `ServiceEventObject`. /// A weak reference to a `ServiceEventObject`.
#[derive(Clone)] #[derive(Clone)]
#[repr(transparent)]
pub struct ServiceEventObjectRef(Weak<dyn Any + Send + Sync + 'static>); pub struct ServiceEventObjectRef(Weak<dyn Any + Send + Sync + 'static>);
shim_debug!(ServiceEventObjectRef); shim_debug!(ServiceEventObjectRef);
@ -110,11 +113,21 @@ impl ServiceEventObjectRef
None => Err(self), None => Err(self),
} }
} }
/// Check if the object has not been destroyed yet.
pub fn is_alive(&self) -> bool
{
self.0.strong_count() > 0
}
} }
impl ServiceEventObject impl ServiceEventObject
{ {
pub fn clone_inner(&self) -> Self
{
Self(Arc::from(self.0.clone_dyn_any_sync()))
}
/// Get a weak reference counted handle to the object, without cloning the object itself. /// Get a weak reference counted handle to the object, without cloning the object itself.
pub fn clone_weak(&self) -> ServiceEventObjectRef pub fn clone_weak(&self) -> ServiceEventObjectRef
{ {
@ -125,7 +138,7 @@ impl ServiceEventObject
/// ///
/// This will fail if: /// This will fail if:
/// * The downcasted type is invalid /// * The downcasted type is invalid
#[inline] pub fn downcast_clone<T: AnyCloneable + Send + Sync + 'static>(&self) -> Option<T> #[inline] pub fn downcast_clone<T: Any + Clone + Send + Sync + 'static>(&self) -> Option<T>
{ {
self.downcast_ref::<T>().map(|x| *x.clone_dyn_any().downcast().unwrap()) self.downcast_ref::<T>().map(|x| *x.clone_dyn_any().downcast().unwrap())
} }
@ -134,7 +147,7 @@ impl ServiceEventObject
/// This will fail if: /// This will fail if:
/// * The downcasted type is invalid /// * The downcasted type is invalid
/// * There are other references to this object (created through `clone_ref()`.). /// * There are other references to this object (created through `clone_ref()`.).
pub fn try_into_downcast<T: AnyCloneable + Send + Sync + 'static>(self) -> Result<T, Self> pub fn try_into_downcast<T: Any + Send + Sync + 'static>(self) -> Result<T, Self>
{ {
match Arc::downcast(self.0) match Arc::downcast(self.0)
{ {
@ -153,12 +166,12 @@ impl ServiceEventObject
} }
/// Try to downcast the object into a concrete type /// Try to downcast the object into a concrete type
#[inline] pub fn is<T: AnyCloneable + Send + Sync + 'static>(&self) -> bool #[inline] pub fn is<T: Any + Send + Sync + 'static>(&self) -> bool
{ {
self.0.as_ref().is::<T>() self.0.as_ref().is::<T>()
} }
/// Try to downcast the object into a concrete type /// Try to downcast the object into a concrete type
#[inline] pub fn downcast_ref<T: AnyCloneable + Send + Sync + 'static>(&self) -> Option<&T> #[inline] pub fn downcast_ref<T: Any + Send + Sync + 'static>(&self) -> Option<&T>
{ {
self.0.as_ref().downcast_ref::<T>() self.0.as_ref().downcast_ref::<T>()
} }
@ -168,7 +181,11 @@ impl ServiceEventObject
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Copy)] #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Copy)]
pub enum ServiceEventKind pub enum ServiceEventKind
{ {
/// Does nothing.
///
/// # Associated object
/// `()`.
Ping,
/// Does nothing. /// Does nothing.
/// ///
/// # Associated object /// # Associated object
@ -190,6 +207,8 @@ cfg_if!{
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct ServiceEvent pub struct ServiceEvent
{ {
bc_id: BroadcastID,
kind: ServiceEventKind, kind: ServiceEventKind,
directed: Option<SESet<ServiceSubID>>, directed: Option<SESet<ServiceSubID>>,
obj: Option<ServiceEventObject>, obj: Option<ServiceEventObject>,
@ -197,8 +216,29 @@ pub struct ServiceEvent
impl ServiceEvent impl ServiceEvent
{ {
/// Create a new event to be broadcast
fn new<T>(kind: ServiceEventKind, directed: Option<impl IntoIterator<Item=ServiceSubID>>, obj: Option<T>) -> Self
where T: Any + Send + Sync + 'static
{
Self {
bc_id: BroadcastID::id_new(),
kind,
directed: directed.map(|x| x.into_iter().collect()).and_then(|n: SESet<_>| if n.len() < 1 {
None
} else {
Some(n)
}),
obj: obj.map(|x| ServiceEventObject(Arc::new(x))),
}
}
#[inline] pub fn id(&self) -> &BroadcastID
{
&self.bc_id
}
/// The kind of this event. /// The kind of this event.
pub fn kind(&self) -> ServiceEventKind #[inline] pub fn kind(&self) -> ServiceEventKind
{ {
self.kind self.kind
} }

Loading…
Cancel
Save