diff options
author | Marcel Müller <m.mueller@ifm.com> | 2022-04-13 13:27:49 +0200 |
---|---|---|
committer | Marcel Müller <m.mueller@ifm.com> | 2022-04-13 13:27:49 +0200 |
commit | 71a8cddc2ae0d8fcaa2bd2a1b459af58b0e86595 (patch) | |
tree | c4f04432aa297bed8514ca7464569864d0d8855d | |
parent | 9ccd86589db8f9a72c4d7f545813e8da40b4d039 (diff) |
Add missing documentation for types
Signed-off-by: Marcel Müller <m.mueller@ifm.com>
-rw-r--r-- | crates/core/tedge_api/src/address.rs | 40 | ||||
-rw-r--r-- | crates/core/tedge_api/src/error.rs | 4 | ||||
-rw-r--r-- | crates/core/tedge_api/src/lib.rs | 13 | ||||
-rw-r--r-- | crates/core/tedge_api/src/plugin.rs | 7 |
4 files changed, 45 insertions, 19 deletions
diff --git a/crates/core/tedge_api/src/address.rs b/crates/core/tedge_api/src/address.rs index 1e498199..581c316a 100644 --- a/crates/core/tedge_api/src/address.rs +++ b/crates/core/tedge_api/src/address.rs @@ -25,20 +25,20 @@ pub type MessageReceiver = tokio::sync::mpsc::Receiver<InternalMessage>; /// An instance of this type represents an address that can be used to send messages of a /// well-defined type to a specific plugin. /// The `Address` instance can be used to send messages of several types, but each type has to be -/// in `MB: MessageBundle`. -pub struct Address<MB: ReceiverBundle> { - _pd: PhantomData<fn(MB)>, +/// in `RB: ReceiverBundle`. +pub struct Address<RB: ReceiverBundle> { + _pd: PhantomData<fn(RB)>, sender: MessageSender, } -impl<MB: ReceiverBundle> std::fmt::Debug for Address<MB> { +impl<RB: ReceiverBundle> std::fmt::Debug for Address<RB> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct(&format!("Address<{}>", std::any::type_name::<MB>())) + f.debug_struct(&format!("Address<{}>", std::any::type_name::<RB>())) .finish_non_exhaustive() } } -impl<MB: ReceiverBundle> Clone for Address<MB> { +impl<RB: ReceiverBundle> Clone for Address<RB> { fn clone(&self) -> Self { Self { _pd: PhantomData, @@ -47,7 +47,7 @@ impl<MB: ReceiverBundle> Clone for Address<MB> { } } -impl<MB: ReceiverBundle> Address<MB> { +impl<RB: ReceiverBundle> Address<RB> { /// THIS IS NOT PART OF THE PUBLIC API, AND MAY CHANGE AT ANY TIME #[doc(hidden)] pub fn new(sender: MessageSender) -> Self { @@ -75,7 +75,7 @@ impl<MB: ReceiverBundle> Address<MB> { /// For details on sending and receiving, see `tokio::sync::mpsc::Sender`. pub async fn send<M: Message>(&self, msg: M) -> Result<ReplyReceiver<M::Reply>, M> where - MB: Contains<M>, + RB: Contains<M>, { let (sender, receiver) = tokio::sync::oneshot::channel(); @@ -95,23 +95,37 @@ impl<MB: ReceiverBundle> Address<MB> { } #[derive(Debug)] +/// Listener that allows one to wait for a reply as sent through [`Address::send`] pub struct ReplyReceiver<M> { _pd: PhantomData<fn(M)>, reply_recv: tokio::sync::oneshot::Receiver<AnySendBox>, } impl<M: Message> ReplyReceiver<M> { + /// Wait for a reply until for the duration given in `timeout` + /// + /// ## Note + /// + /// Plugins could not reply for any number of reasons, hence waiting indefinitely on a reply + /// can cause problems in long-running applications. As such, one needs to specify how long a + /// reply should take before another action be taken. + /// + /// It is also important, that just because a given `M: Message` has a `M::Reply` type set, + /// that the plugin that a message was sent to does _not_ have to reply with it. It can choose + /// to not do so. pub async fn wait_for_reply(self, timeout: Duration) -> Result<M, ReplyError> { let data = tokio::time::timeout(timeout, self.reply_recv) .await .map_err(|_| ReplyError::Timeout)? - .map_err(|_| ReplyError::Unknown)?; + .map_err(|_| ReplyError::SendSideClosed)?; Ok(*data.downcast().expect("Invalid type received")) } } #[derive(Debug)] +/// Allows the [`Handle`](crate::plugin::Handle) implementation to reply with a given message as +/// specified by the currently handled message. pub struct ReplySender<M> { _pd: PhantomData<fn(M)>, reply_sender: tokio::sync::oneshot::Sender<AnySendBox>, @@ -125,6 +139,7 @@ impl<M: Message> ReplySender<M> { } } + /// Reply to the originating plugin with the given message pub fn reply(self, msg: M) -> Result<(), M> { self.reply_sender .send(Box::new(msg)) @@ -142,11 +157,16 @@ impl<M: Message> ReplySender<M> { } #[derive(Debug, thiserror::Error)] +/// An error occured while replying pub enum ReplyError { + /// The timeout elapsed before the other plugin responded #[error("There was no response before timeout")] Timeout, + /// The other plugin dropped its sending side + /// + /// This means that there will never be an answer #[error("Could not send reply")] - Unknown, + SendSideClosed, } #[doc(hidden)] diff --git a/crates/core/tedge_api/src/error.rs b/crates/core/tedge_api/src/error.rs index a84110fd..7f6c8f8e 100644 --- a/crates/core/tedge_api/src/error.rs +++ b/crates/core/tedge_api/src/error.rs @@ -1,13 +1,17 @@ use miette::Diagnostic; use thiserror::Error; +/// Errors as orginating from [`Plugin`](crate::Plugin) and [`PluginBuilder`](crate::PluginBuilder) pub type PluginError = miette::Report; #[derive(Error, Debug, Diagnostic)] +/// An error occured while interfacing with the [`PluginDirectory`](crate::plugin::PluginDirectory) pub enum DirectoryError { + /// The given plugin name does not exist in the configuration #[error("Plugin named '{}' not found", .0)] PluginNameNotFound(String), + /// The given plugin does not support all requested message types #[error("Plugin '{}' does not support the following message types: {}", .0 ,.1.join(","))] PluginDoesNotSupport(String, Vec<&'static str>), } diff --git a/crates/core/tedge_api/src/lib.rs b/crates/core/tedge_api/src/lib.rs index 3ebb4a20..c2e793f4 100644 --- a/crates/core/tedge_api/src/lib.rs +++ b/crates/core/tedge_api/src/lib.rs @@ -1,11 +1,8 @@ -#![cfg_attr( - test, - deny( - missing_docs, - missing_debug_implementations, - unreachable_pub, - unsafe_code, - ) +#![deny( + missing_docs, + missing_debug_implementations, + unreachable_pub, + unsafe_code )] #![doc = include_str!("../README.md")] diff --git a/crates/core/tedge_api/src/plugin.rs b/crates/core/tedge_api/src/plugin.rs index b538d7fc..89caeab7 100644 --- a/crates/core/tedge_api/src/plugin.rs +++ b/crates/core/tedge_api/src/plugin.rs @@ -51,7 +51,7 @@ pub trait PluginDirectory: Send + Sync { fn get_address_for_core(&self) -> Address<CoreMessages>; } -/// The plugin configuration as a `toml::Spanned` table. +/// The plugin configuration as a TOML [`Value`](toml::value::Value) /// /// It is important that configuration errors are communicated precisely /// and concisely. Reporting the span is not a must, but greatly helps users @@ -317,7 +317,11 @@ pub trait Plugin: Sync + Send + DowncastSync { impl_downcast!(sync Plugin); +/// A trait declaring what messages a plugin purports to handle +/// +/// This is then used by [`PluginExt`] to make writing a [`PluginBuilder`] easier. pub trait PluginDeclaration: Plugin { + /// A [`MessageBundle`] of types this plugin handles. type HandledMessages: MessageBundle; } @@ -428,6 +432,7 @@ impl From<HandleTypes> for HashSet<(&'static str, TypeId)> { /// A message without the expectation of a reply can use the [`NoReply`](crate::message::NoReply) /// type. pub trait Message: 'static + Send + std::fmt::Debug { + /// The reply to this message type Reply: Message; } |