diff --git a/README.md b/README.md index ede6dbf..2901f82 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ distributed actors. It has three dependencies: - serde_json - serde_repr -For a simple example, see the [gg-echo](https://git.kittencollective.com/nebkor/chatty-catties/src/branch/main/gg-echo/src/main.rs) program: +For a simple example, see the [echo](https://git.kittencollective.com/nebkor/nebkor-maelstrom/src/branch/main/examples/echo.rs) example: ``` rust use nebkor_maelstrom::{Body, Message, Node, Runner}; @@ -34,6 +34,23 @@ fn main() { } ``` +For a slightly more complicated example, check out the +[broadcast](https://git.kittencollective.com/nebkor/nebkor-maelstrom/src/branch/main/examples/broadcast.rs) +example, which passes the [single-node](https://fly.io/dist-sys/3a/) challenge, but utterly fails +even the friendliest (eg, no partitions or lag) multi-node challenge, so hopefully is not giving too +much away. + +## Features + + - no async + - minimal boilerplate + - working RPC calls (allowing the main thread to call out to other nodes and receive a reply while + already handling a message) + - proxies for the [Maelstrom KV + services](https://github.com/jepsen-io/maelstrom/blob/main/doc/services.md) that use the RPC + mechanism to provide `read`, `write`, and `cas` operations, and return + `Result, ErrorCode>`s to the caller + ## How to use Create a struct and implement `nebkor_maelstrom::Node` for it, which involves a single method, @@ -41,10 +58,10 @@ Create a struct and implement `nebkor_maelstrom::Node` for it, which involves a `send`, `reply`, and `rpc`. In your main function, instantiate that struct and pass that into `Runner::new()` to get a -Runner. The `run()` method takes an optional closure that will be run when the `init` Message is +Runner. The `run()` method takes an optional callback that will be run when the `init` Message is received; see the -[broadcast](https://git.kittencollective.com/nebkor/chatty-catties/src/commit/af6d2c0b2720669f91a758c8c5755a146a914be4/gg-broadcast/src/main.rs#L10-L30) -program for an example of that, where it spawns a thread to send periodic messages to the node. +[broadcast](https://git.kittencollective.com/nebkor/nebkor-maelstrom/src/commit/c45b179de45ba7e03a884d6c7cdb4c1c2625ae20/examples/broadcast.rs#L8-L20) +example, where it spawns a thread from the callback to send periodic messages to the node. ## Design considerations @@ -54,8 +71,18 @@ you need to, without the ceremony of `Rc>` and the like. Eschewing `asyn order of magnitude fewer dependencies, and the entire workspace (crate and clients) can be compiled in a couple seconds. +It also assumes that some things are infallible. For example, there's liberal `unwrap()`ing when +calling `send()` or `recv()` on MPSC channels, because those kinds of errors are not part of the +Maelstrom protocol; this crate is not a general-purpose network client crate for the real +world. Likewise `stdin` and `stdout` are always assumed to be available and reliable; those two +channels are the physical layer for connecting a node to the Maelstrom router, and failures there +are out of scope for Gossip Glomers. + +A final consideration is understandability of the crate itself; you should not have a hard time +diving into its source from your IDE or browser. + ## Acknowledgments I straight-up stole the design of the IO/network system from [Maelbreaker](https://github.com/rafibayer/maelbreaker/), which allowed me to get a working RPC -call. Thanks! +call. Thanks! And thanks to Nicole for nudging me to publish this.