diff --git a/README.md b/README.md index 6cab965..5febcda 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ for the specific struct field. Therefore, if you see a compile time error that b not set prior to the `build` call. To exclude subsystems from such a check, one can set `wip` attribute on some subsystem that -is not ready to be included in the Orchestra: +is not ready to be included in the `orchestra`: ```rust #[orchestra(signal=SigSigSig, event=Event, gen=AllMessages, error=OrchestraError)] @@ -104,6 +104,31 @@ The path to the generated file will be displayed and is of the form Use `dot -Tpng ${OUT_DIR}/${orchestra|lowercase}-subsystem-messaging.dot > connectivity.dot` to convert to i.e. a `png` image or use your favorite dot file viewer. +## Caveats + +No tool is without caveats, and `orchestra` is no exception. + +### Large Message Types + +It is not recommended to have large messages that are sent via channels, just like for other +implementations of channels. +If you need to transfer data that is larger than a few dozend bytes, use `Box<_>` around it or use a global identifier to access persisted state such as a database, depending on the use case. + +### Response Channels + +It seems very appealing to have response channels as part of messages, and for many cases, +these are a very convenient way of maintaining a strucutured data flow, yet they are ready +to shoot you in the foot when not used diligently. The diligence required is regarding three +topics: + +1. Circular message dependencies leading to a dead-lock for single threaded subsystems +2. Too deep message dependencies across _many_ subsystems +3. Delays due to response channels + +Each of them has a variety of solutions, such as local caching to remedy frequent lookups of the same information or splitting up subsystem into multiple to avoid circular dependencies or merging tiny topologically closely related to one subsystem in some exceptional cases, but strongly depend on the individual context in which orchestra is used. + +To find these, the feature `dotgraph` is providing a visualization of all interactions of the subsystem to subsystem level (not on the message level, yet) to investigate cycles. +Keep an eye on warnings during the generation phase. ## License diff --git a/orchestra/src/lib.rs b/orchestra/src/lib.rs index eadaa33..8212baf 100644 --- a/orchestra/src/lib.rs +++ b/orchestra/src/lib.rs @@ -15,19 +15,17 @@ //! # Orchestra //! -//! `orchestra` provides a global information flow of what a token of information. +//! `orchestra` provides a global information flow system in reference to system specifc +//! process tokens. //! The token is arbitrary, but is used to notify all `Subsystem`s of what is relevant -//! and what is not. +//! and what is not, leading to a so called _view_ of active tokens. //! -//! For the motivations behind implementing the orchestra itself you should -//! check out that guide, documentation in this crate will focus and be of -//! technical nature. -//! -//! An `Orchestra` is something that allows spawning/stopping and orchestrating +//! An `orchestra` is something that allows spawning/stopping and orchestrating //! asynchronous tasks as well as establishing a well-defined and easy to use //! protocol that the tasks can use to communicate with each other. It is desired -//! that this protocol is the only way tasks communicate with each other, however -//! at this moment there are no foolproof guards against other ways of communication. +//! that this protocol is the only way tasks - called `Subsystem`s in the orchestra +//! scope - communicate with each other, but that is not enforced and is the responsibility +//! of the developer. //! //! The `Orchestra` is instantiated with a pre-defined set of `Subsystems` that //! share the same behavior from `Orchestra`'s point of view. @@ -47,17 +45,17 @@ //! .................................................................. //! | | //! start() start() +//! | | //! V V -//! ..................| Orchestra "runs" these |....................... +//! ..................| Orchestra "runs" these |...................... +//! . . //! . +--------------------+ +---------------------+ . //! . | SubsystemInstance1 | <-- bidir --> | SubsystemInstance2 | . //! . +--------------------+ +---------------------+ . +//! . . //! .................................................................. //! ``` - -// #![deny(unused_results)] -// unused dependencies can not work for test and examples at the same time -// yielding false positives +#![deny(unused_results)] #![deny(missing_docs)] #![deny(unused_crate_dependencies)] @@ -231,7 +229,7 @@ impl SignalsReceived { /// Increase the number of signals by one. pub fn inc(&self) { - self.0.fetch_add(1, atomic::Ordering::AcqRel); + let _previous = self.0.fetch_add(1, atomic::Ordering::AcqRel); } }