Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: docs and clippy chores #49

Merged
merged 2 commits into from
Jul 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down Expand Up @@ -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

Expand Down
28 changes: 13 additions & 15 deletions orchestra/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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)]

Expand Down Expand Up @@ -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);
}
}

Expand Down