attempt no.1, overcomplex failure

clone-session-service-objects
Avril 4 years ago
parent f66f5a6565
commit 13cb323ed3
Signed by: flanchan
GPG Key ID: 284488987C31F630

199
Cargo.lock generated

@ -1,5 +1,40 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
[[package]]
name = "addr2line"
version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a55f82cfe485775d02112886f4169bde0c5894d75e79ead7eafe7e40a25e45f7"
dependencies = [
"gimli",
]
[[package]]
name = "adler"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
[[package]]
name = "aho-corasick"
version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
dependencies = [
"memchr",
]
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi 0.3.9",
]
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "0.1.7" version = "0.1.7"
@ -12,6 +47,20 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "backtrace"
version = "0.3.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef5140344c85b01f9bbb4d4b7288a8aa4b3287ccef913a14bcc78a1063623598"
dependencies = [
"addr2line",
"cfg-if 1.0.0",
"libc",
"miniz_oxide",
"object",
"rustc-demangle",
]
[[package]] [[package]]
name = "base64" name = "base64"
version = "0.12.3" version = "0.12.3"
@ -115,6 +164,19 @@ dependencies = [
"bitflags", "bitflags",
] ]
[[package]]
name = "color-eyre"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b29030875fd8376e4a28ef497790d5b4a7843d8d1396bf08ce46f5eec562c5c"
dependencies = [
"backtrace",
"eyre",
"indenter",
"once_cell",
"owo-colors",
]
[[package]] [[package]]
name = "cpuid-bool" name = "cpuid-bool"
version = "0.1.2" version = "0.1.2"
@ -190,6 +252,29 @@ version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88d7ed2934d741c6b37e33e3832298e8850b53fd2d2bea03873375596c7cea4e" checksum = "88d7ed2934d741c6b37e33e3832298e8850b53fd2d2bea03873375596c7cea4e"
[[package]]
name = "env_logger"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
dependencies = [
"atty",
"humantime",
"log",
"regex",
"termcolor",
]
[[package]]
name = "eyre"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "221239d1d5ea86bf5d6f91c9d6bc3646ffe471b08ff9b0f91c44f115ac969d2b"
dependencies = [
"indenter",
"once_cell",
]
[[package]] [[package]]
name = "fake-simd" name = "fake-simd"
version = "0.1.2" version = "0.1.2"
@ -394,6 +479,12 @@ dependencies = [
"wasi 0.10.0+wasi-snapshot-preview1", "wasi 0.10.0+wasi-snapshot-preview1",
] ]
[[package]]
name = "gimli"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6503fe142514ca4799d4c26297c4248239fe8838d827db6bd6065c6ed29a6ce"
[[package]] [[package]]
name = "h2" name = "h2"
version = "0.2.7" version = "0.2.7"
@ -503,6 +594,15 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47" checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47"
[[package]]
name = "humantime"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
dependencies = [
"quick-error",
]
[[package]] [[package]]
name = "hyper" name = "hyper"
version = "0.13.9" version = "0.13.9"
@ -538,6 +638,12 @@ dependencies = [
"unicode-normalization", "unicode-normalization",
] ]
[[package]]
name = "indenter"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4d5eb2e114fec2b7fe0fadc22888ad2658789bb7acac4dbee9cf8389f971ec8"
[[package]] [[package]]
name = "indexmap" name = "indexmap"
version = "1.6.1" version = "1.6.1"
@ -631,6 +737,16 @@ dependencies = [
"unicase", "unicase",
] ]
[[package]]
name = "miniz_oxide"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f2d26ec3309788e423cfbf68ad1800f061638098d76a83681af979dc4eda19d"
dependencies = [
"adler",
"autocfg 1.0.1",
]
[[package]] [[package]]
name = "mio" name = "mio"
version = "0.6.23" version = "0.6.23"
@ -695,6 +811,12 @@ dependencies = [
"winapi 0.3.9", "winapi 0.3.9",
] ]
[[package]]
name = "mopa"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a785740271256c230f57462d3b83e52f998433a7062fc18f96d5999474a9f915"
[[package]] [[package]]
name = "multipart" name = "multipart"
version = "0.17.0" version = "0.17.0"
@ -734,6 +856,12 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "object"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d3b63360ec3cb337817c2dbd47ab4a0f170d285d8e5a2064600f3def1402397"
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.5.2" version = "1.5.2"
@ -779,6 +907,12 @@ dependencies = [
"vcpkg", "vcpkg",
] ]
[[package]]
name = "owo-colors"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13370dae44474229701bb69b90b4f4dca6404cb0357a2d50d635f1171dc3aa7b"
[[package]] [[package]]
name = "pbkdf2" name = "pbkdf2"
version = "0.5.0" version = "0.5.0"
@ -870,6 +1004,16 @@ version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
[[package]]
name = "pretty_env_logger"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d"
dependencies = [
"env_logger",
"log",
]
[[package]] [[package]]
name = "proc-macro-hack" name = "proc-macro-hack"
version = "0.5.19" version = "0.5.19"
@ -1068,6 +1212,24 @@ version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[package]]
name = "regex"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
"thread_local",
]
[[package]]
name = "regex-syntax"
version = "0.6.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581"
[[package]] [[package]]
name = "remove_dir_all" name = "remove_dir_all"
version = "0.5.3" version = "0.5.3"
@ -1077,6 +1239,12 @@ dependencies = [
"winapi 0.3.9", "winapi 0.3.9",
] ]
[[package]]
name = "rustc-demangle"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232"
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.5" version = "1.0.5"
@ -1242,6 +1410,24 @@ dependencies = [
"winapi 0.3.9", "winapi 0.3.9",
] ]
[[package]]
name = "termcolor"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
dependencies = [
"winapi-util",
]
[[package]]
name = "thread_local"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb9bc092d0d51e76b2b19d9d85534ffc9ec2db959a2523cdae0697e2972cd447"
dependencies = [
"lazy_static",
]
[[package]] [[package]]
name = "time" name = "time"
version = "0.1.44" version = "0.1.44"
@ -1564,6 +1750,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi 0.3.9",
]
[[package]] [[package]]
name = "winapi-x86_64-pc-windows-gnu" name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0" version = "0.4.0"
@ -1584,13 +1779,17 @@ dependencies = [
name = "yuurei" name = "yuurei"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"color-eyre",
"cryptohelpers", "cryptohelpers",
"difference", "difference",
"futures", "futures",
"generational-arena", "generational-arena",
"getrandom 0.2.1", "getrandom 0.2.1",
"lazy_static", "lazy_static",
"log",
"mopa",
"once_cell", "once_cell",
"pretty_env_logger",
"serde", "serde",
"sha2", "sha2",
"smallvec", "smallvec",

@ -11,13 +11,17 @@ default = ["nightly"]
nightly = ["smallvec/const_generics"] nightly = ["smallvec/const_generics"]
[dependencies] [dependencies]
color-eyre = {version = "0.5.10", default-features=false}
cryptohelpers = {version = "1.7.1", features=["full"]} cryptohelpers = {version = "1.7.1", features=["full"]}
difference = "2.0.0" difference = "2.0.0"
futures = "0.3.8" futures = "0.3.8"
generational-arena = "0.2.8" generational-arena = "0.2.8"
getrandom = "0.2.1" getrandom = "0.2.1"
lazy_static = "1.4.0" lazy_static = "1.4.0"
log = "0.4.11"
mopa = "0.2.2"
once_cell = "1.5.2" once_cell = "1.5.2"
pretty_env_logger = "0.4.0"
serde = {version = "1.0.118", features=["derive"]} serde = {version = "1.0.118", features=["derive"]}
sha2 = "0.9.2" sha2 = "0.9.2"
smallvec = {version = "1.6.0", features= ["union", "serde", "write"]} smallvec = {version = "1.6.0", features= ["union", "serde", "write"]}

@ -519,13 +519,13 @@ pub type MaybeVec<T> = smallvec::SmallVec<[T; 1]>;
} }
} }
$( $(
impl $($($frag)*)? ::std::ops::DerefMut for $name impl $($($frag)*)? ::std::ops::DerefMut for $name
{
fn deref_mut(&mut self) -> &mut <Self as ::std::ops::Deref>::Target
{ {
$mut_expr fn deref_mut(&mut self) -> &mut <Self as ::std::ops::Deref>::Target
} {
})? $mut_expr
}
})?
}; };
} }
@ -533,3 +533,48 @@ pub type MaybeVec<T> = smallvec::SmallVec<[T; 1]>;
#[macro_export] macro_rules! ignore { #[macro_export] macro_rules! ignore {
($expr:expr) => ({let _ = $expr;}); ($expr:expr) => ({let _ = $expr;});
} }
use std::any::Any;
/// A trait for `Any` that is both `Send`, `Sync`, `'static`, and implements `Clone`.
pub trait AnyCloneable: mopa::Any
{
fn clone_dyn(&self) -> Box<dyn AnyCloneable + Send + Sync + 'static>;
fn clone_dyn_any(&self) -> Box<dyn Any + Send + 'static>;
}
mopafy!(AnyCloneable);
impl<T: ?Sized + Clone + Any + Send + Sync + 'static> AnyCloneable for T
{
#[inline] fn clone_dyn(&self) -> Box<dyn AnyCloneable + Send + Sync + 'static> {
Box::new(self.clone())
}
#[inline] fn clone_dyn_any(&self) -> Box<dyn Any + Send + 'static> {
Box::new(self.clone())
}
}
/// A dynamically clonable heap allocated polymorphic `Any` object.
pub type DynCloneable = Box<dyn AnyCloneable + Send + Sync + 'static>;
impl Clone for DynCloneable
{
#[inline] fn clone(&self) -> Self {
self.clone_dyn()
}
}
#[macro_export] macro_rules! shim_debug {
($name:ident; $msg:literal $($tt:tt)*) => {
impl ::std::fmt::Debug for $name
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f, $msg $($tt)*)
}
}
};
($name:ident) => {
shim_debug!($name; "<opaque debug for type {:?}>", std::any::type_name::<$name>());
}
}

@ -6,8 +6,19 @@
#[cfg(all(feature="nightly", test))] extern crate test; #[cfg(all(feature="nightly", test))] extern crate test;
#[macro_use] extern crate serde; #[macro_use] extern crate serde;
#[macro_use] extern crate lazy_static; #[macro_use] extern crate lazy_static;
#[macro_use] extern crate log;
#[macro_use] extern crate mopa;
use std::convert::{TryFrom, TryInto}; use std::convert::{TryFrom, TryInto};
use color_eyre::{
eyre::{
WrapErr as _,
self,
eyre,
},
SectionExt, Help
};
#[macro_use] mod ext; use ext::*; #[macro_use] mod ext; use ext::*;
mod bytes; mod bytes;
@ -16,7 +27,18 @@ mod delta;
mod state; mod state;
mod service; mod service;
fn install() -> eyre::Result<()>
{
color_eyre::install()?;
pretty_env_logger::init();
Ok(())
}
#[tokio::main] #[tokio::main]
async fn main() { async fn main() -> eyre::Result<()> {
install()?;
println!("Hello, world!"); println!("Hello, world!");
Ok(())
} }

@ -14,7 +14,7 @@ use std::marker::{Send,Sync};
//pub type BoxedMessage = Box<dyn std::any::Any + Send + Sync + 'static>; //pub type BoxedMessage = Box<dyn std::any::Any + Send + Sync + 'static>;
/// A handle to a service. /// A handle to a service.
pub trait Service<T=()> pub trait Service<T=ExitStatus>
where T: Send + 'static where T: Send + 'static
{ {
/// The message type to send to the service. /// The message type to send to the service.
@ -67,3 +67,68 @@ impl fmt::Display for SubscribeError
} }
} }
} }
#[macro_export] macro_rules! join_service {
($serv:expr) => ($serv.await.map_err(|_| $crate::service::ExitStatus::Abnormal)?)
}
/// How a service exited
#[derive(Debug)]
#[non_exhaustive]
pub enum ExitStatus<T=()>
{
/// A graceful exit with value
Graceful(T),
/// An abnormal exit (counted as error)
///
/// # Usage
/// Usually for panicked services, otherwise use `Self::Error`.
/// The macro `join_service!()` can be used to convert handle join errors into this
Abnormal,
/// Exit on an error report (counted as error)
Error(eyre::Report),
}
#[derive(Debug)]
/// The error `ExitStatus::Abnormal` converts to.
pub struct AbnormalExitError;
impl error::Error for AbnormalExitError{}
impl fmt::Display for AbnormalExitError
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f, "service terminated in an abnormal way")
}
}
impl<U, T: error::Error + Send+Sync+'static> From<T> for ExitStatus<U>
{
fn from(from: T) -> Self
{
Self::Error(from.into())
}
}
impl<T: Default> Default for ExitStatus<T>
{
#[inline]
fn default() -> Self
{
Self::Graceful(T::default())
}
}
impl<T> From<ExitStatus<T>> for eyre::Result<T>
{
fn from(from: ExitStatus<T>) -> Self
{
match from {
ExitStatus::Abnormal => Err(AbnormalExitError).with_note(|| "The background worker likely panicked"),
ExitStatus::Graceful(t) => Ok(t),
ExitStatus::Error(rep) => Err(rep).wrap_err(AbnormalExitError),
}
}
}

@ -12,6 +12,7 @@ pub mod user;
pub mod post; pub mod post;
pub mod body; pub mod body;
mod service; pub use service::*;
mod freeze; pub use freeze::*; mod freeze; pub use freeze::*;
/// Entire post state container /// Entire post state container
@ -65,3 +66,4 @@ impl State
self.0.posts.write().await self.0.posts.write().await
} }
} }

@ -0,0 +1,303 @@
//! Global state service
use super::*;
use tokio::{
sync::{
watch,
mpsc,
oneshot,
broadcast,
},
task::JoinHandle,
};
use crate::service::{
ExitStatus,
};
use std::{error, fmt};
use std::sync::Weak;
use std::any::Any;
use std::collections::BTreeMap;
id_type!(ServiceSubID; "Optional ID for filtering directed broadcast messages");
/// Signal the shutdown method to the supervisor.
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)]
pub enum SupervisorShutdownStatus
{
/// Signal the subtask(s) to shut down, then wait for them and exit.
Signal,
/// Drop all handles and pipes to subtask(s) then immediately exit.
Drop,
/// Keep working
Normal,
/// Restart any and all subtask(s)
Restart,
}
impl Default for SupervisorShutdownStatus
{
#[inline]
fn default() -> Self
{
SupervisorShutdownStatus::Normal
}
}
/// The kind of command to send to the the service
#[derive(Debug)]
pub enum ServiceCommandKind
{
}
#[derive(Debug)]
pub enum ServiceResponseKind
{
}
#[derive(Debug)]
pub struct ServiceResponse(Option<ServiceCommandKind>);
#[derive(Debug)]
pub struct ServiceCommand
{
kind: ServiceCommandKind,
output: oneshot::Sender<ServiceResponse>,
}
/// Supervisor responsible for spawning the state handler service.
#[derive(Debug)]
pub(super) struct Supervisor
{
handle: JoinHandle<ExitStatus>,
shutdown: watch::Sender<SupervisorShutdownStatus>,
pipe: mpsc::Sender<ServiceCommand>,
sub: BTreeMap<ServiceEventKind, ServiceEvent>
}
/// Object sent through the broadcast channel.
///
/// These objects can be cloned and downcasted, but can also be atomically refcounted if that is more desireable.
///
/// # Cloning
/// The implementation of `Clone` for this instance clones the inner object, not the refcount. Use `clone_ref()` to *just* clone the refcount.
/// To downcast and clone the inner object without an extra `Arc` allocation, use `downcast_clone()` or `downcast().map(Clone::clone)`.
pub struct ServiceEventObject(Arc<dyn AnyCloneable + Send + Sync + 'static>);
shim_debug!(ServiceEventObject);
/// A weak reference to a `ServiceEventObject`.
#[derive(Clone)]
pub struct ServiceEventObjectRef(Weak<dyn AnyCloneable + Send + Sync + 'static>);
shim_debug!(ServiceEventObjectRef);
/// Wrapper used when broadcasting to prevent useless inner object clones.
#[derive(Debug)]
struct EventObjectRefCloneWrap(ServiceEventObject);
impl Clone for EventObjectRefCloneWrap
{
fn clone(&self) -> Self {
Self(self.0.clone_ref())
}
}
impl Clone for ServiceEventObject
{
fn clone(&self) -> Self {
Self(Arc::from(self.0.as_ref().clone_dyn()))
}
}
impl ServiceEventObjectRef
{
/// Try to upgrade to a concrete reference, and then clone the inner object.
pub fn try_clone(&self) -> Option<ServiceEventObject>
{
match self.0.upgrade()
{
Some(arc) => Some(ServiceEventObject(arc).clone()),
None => None
}
}
/// Try to upgrade to a concrete reference.
pub fn upgrade(self) -> Result<ServiceEventObject, Self>
{
match self.0.upgrade()
{
Some(arc) => Ok(ServiceEventObject(arc)),
None => Err(self),
}
}
}
impl ServiceEventObject
{
/// Get an owned reference counted handle to the object, without cloning the object itself.
pub fn clone_ref(&self) -> Self
{
Self(Arc::clone(&self.0))
}
/// Get a weak reference counted handle to the object, without cloning the object itself.
pub fn clone_weak(&self) -> ServiceEventObjectRef
{
ServiceEventObjectRef(Arc::downgrade(&self.0))
}
/// Try to downcast the inner object to a concrete type and then clone it.
///
/// This will fail if:
/// * The downcasted type is invalid
#[inline] pub fn downcast_clone<T: AnyCloneable + Send + Sync + 'static>(&self) -> Option<T>
{
self.downcast_ref::<T>().map(|x| *x.clone_dyn_any().downcast().unwrap())
}
/// Try to consume this instance into downcast.
///
/// This will fail if:
/// * The downcasted type is invalid
/// * 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>
{
match Arc::downcast(self.0)
{
Ok(v) => v,
Err(e) => Self(e),
}
}
/// Check if there are any other references to this object
#[inline] pub fn is_unique(&self) -> bool
{
Arc::strong_count(&self.0) == 1
}
/// Try to downcast the object into a concrete type
#[inline] pub fn is<T: AnyCloneable + Send + Sync + 'static>(&self) -> Option<&T>
{
self.0.is()
}
/// Try to downcast the object into a concrete type
#[inline] pub fn downcast_ref<T: AnyCloneable + Send + Sync + 'static>(&self) -> Option<&T>
{
self.0.downcast_ref()
}
}
/// The kind of event outputted from a state service's broadcast stream
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Copy)]
pub enum ServiceEventKind
{
/// Does nothing.
///
/// # Associated object
/// None.
KeepAlive,
}
/// An event outputted from a state service's broadcast stream
#[derive(Debug, Clone)]
pub struct ServiceEvent
{
kind: ServiceEventKind,
directed: Option<MaybeVec<ServiceSubID>>,
obj: Option<EventObjectRefCloneWrap>,
}
impl ServiceEvent
{
/// The kind of this event.
pub fn kind(&self) -> ServiceEventKind
{
self.kind
}
/// Check if this event is for you
pub fn is_directed_for(&self, whom: &ServiceSubID) -> bool
{
if let Some(yes) = self.directed.as_ref() {
yes == whom
} else {
false
}
}
/// Check if this event is directed to anyone
pub fn is_directed(&self) -> bool
{
self.directed.is_some()
}
/// Check who this event is directed to.
///
/// If it is not directed, an empty slice will be returned.
pub fn directed_to(&self) -> &[&ServiceSubID]
{
match self.directed.as_ref()
{
Some(yes) => &yes[..],
None => &[],
}
}
/// Get a reference to the object, if there is one.
pub fn obj_ref(&self) -> Option<&ServiceEventObject>
{
self.obj.as_ref().map(|x| x.0)
}
/// Get a mutable reference to the object, if there is one.
pub fn obj_mut(&mut self) -> Option<&mut ServiceEventObject>
{
self.obj.as_mut().map(|x| x.0)
}
/// Try to consume into the inner object. If there is no object, return self.
pub fn try_into_object(self) -> Result<ServiceEventObject, Self>
{
match self.obj
{
Some(obj) => Ok(obj),
None => Err(self),
}
}
}
impl From<ServiceEvent> for Option<ServiceEventObject>
{
#[inline] fn from(from: ServiceEvent) -> Self
{
from.obj
}
}
impl TryFrom<ServiceEvent> for ServiceEventObject
{
type Error = NoObjectError;
#[inline] fn try_from(from: ServiceEvent) -> Result<Self, Self::Error>
{
match from.obj
{
Some(obj) => Ok(obj.0),
None => Err(NoObjectError),
}
}
}
#[derive(Debug)]
/// Error returned from trying to extract an object from a `ServiceEvent` which has none.
pub struct NoObjectError;
impl error::Error for NoObjectError{}
impl fmt::Display for NoObjectError
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f, "there was no object broadcasted along with this ")
}
}

@ -9,7 +9,7 @@ use tokio::{
task::JoinHandle, task::JoinHandle,
}; };
use std::sync::Arc; use std::sync::Arc;
use service::SubscribeError; use crate::service::{self, SubscribeError};
id_type!(SessionID; "A unique session ID, not bound to a user."); id_type!(SessionID; "A unique session ID, not bound to a user.");
@ -121,25 +121,25 @@ impl Session
} }
} }
impl service::Service for Session // impl service::Service for Session
{ // {
type Message = SessionCommand; // type Message = SessionCommand;
type Response = SessionResponse; // type Response = SessionResponse;
#[inline] fn wait_on(self) -> JoinHandle<()> { // #[inline] fn wait_on(self) -> JoinHandle<()> {
self.handle // self.handle
} // }
#[inline] fn message_in_ref(&self) -> &mpsc::Sender<Self::Message> { // #[inline] fn message_in_ref(&self) -> &mpsc::Sender<Self::Message> {
&self.tx // &self.tx
} // }
#[inline] fn message_in(&mut self) -> &mut mpsc::Sender<Self::Message> { // #[inline] fn message_in(&mut self) -> &mut mpsc::Sender<Self::Message> {
&mut self.tx // &mut self.tx
} // }
#[inline] fn message_out(&mut self) -> &mut broadcast::Receiver<Self::Response> { // #[inline] fn message_out(&mut self) -> &mut broadcast::Receiver<Self::Response> {
&mut self.rx // &mut self.rx
} // }
#[inline] fn is_alive(&self) -> Option<bool> { // #[inline] fn is_alive(&self) -> Option<bool> {
Some(Arc::strong_count(&self.meta) > 1) // Some(Arc::strong_count(&self.meta) > 1)
} // }
} // }

Loading…
Cancel
Save