Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Difference From ump-0.11.0 To ump-0.12.0
2023-08-31
| ||
14:34 | Document ReplyContext. check-in: 61295fc1c3 user: jan tags: trunk | |
2023-08-14
| ||
23:03 | Release maintenance. check-in: b08bb813bf user: jan tags: trunk, ump-0.12.0 | |
22:55 | Update swctx to 0.2.1. check-in: 3eaac7ef46 user: jan tags: trunk | |
2023-07-29
| ||
02:10 | Make a note about project status. check-in: eb09b3724b user: jan tags: trunk | |
2023-07-28
| ||
22:19 | Release maintenance. check-in: bfeac614fd user: jan tags: trunk, ump-0.11.0 | |
22:11 | Return the correct Error type from ReplyContext methods. Documentation updates. check-in: 8ef3a429d7 user: jan tags: trunk | |
Changes to .efiles.
1 2 3 4 5 6 7 8 9 | Cargo.toml README.md www/index.md www/changelog.md src/err.rs src/lib.rs src/server.rs src/client.rs src/rctx.rs | < < < | 1 2 3 4 5 6 7 8 9 10 11 12 | Cargo.toml README.md www/index.md www/changelog.md src/err.rs src/lib.rs src/server.rs src/client.rs src/rctx.rs tests/*.rs examples/*.rs benches/*.rs |
Changes to Cargo.toml.
1 2 | [package] name = "ump" | | < | | < | > > | > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | [package] name = "ump" version = "0.12.0" edition = "2021" license = "0BSD" categories = [ "concurrency", "asynchronous" ] keywords = [ "channel", "threads", "sync", "message-passing" ] repository = "https://repos.qrnch.tech/pub/ump" description = "Micro message passing library for threads/tasks communication." rust-version = "1.56" # Can't exclude "benches", because the [[bench]] section will fail. exclude = [ ".efiles", ".fossil-settings", ".fslckout", "examples", "www", "rustfmt.toml" ] [features] dev-docs = [] [dependencies] parking_lot = { version = "0.12.1" } sigq = { version = "0.13.3" } swctx = { version = "0.2.1" } [dev-dependencies] criterion = { version = "0.5.1", features = ["async_tokio"] } tokio = { version = "1.31.0", features = ["rt-multi-thread"] } [[bench]] name = "add_server" harness = false [package.metadata.docs.rs] rustdoc-args = ["--generate-link-to-definition"] |
Changes to src/client.rs.
|
| | | 1 2 3 4 5 6 7 8 | use crate::{err::Error, server::ServerQueueNode}; /// Representation of a clonable client object. /// /// Each instantiation of a `Client` object is itself an isolated client with /// regards to the server context. By cloning a client a new independent /// client is created. ("Independent" here meaning that it is still tied to /// the same server object, but the new client can be passed to a separate |
︙ | ︙ | |||
49 50 51 52 53 54 55 | // Create a per-call reply context. // This context could be created when the Client object is being created // and stored in the context, and thus be reused for reach client call. // One side-effect is that some of the state semantics becomes more // complicated. // The central repo has such an implementation checked in, but it seems to // have some more corner cases that aren't properly handled. | | | < | | | | < | < | 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | // Create a per-call reply context. // This context could be created when the Client object is being created // and stored in the context, and thus be reused for reach client call. // One side-effect is that some of the state semantics becomes more // complicated. // The central repo has such an implementation checked in, but it seems to // have some more corner cases that aren't properly handled. let (sctx, wctx) = swctx::mkpair(); self .qpusher .push(ServerQueueNode { msg: out, reply: sctx }) .map_err(|_| Error::ServerDisappeared)?; // Wait for a reply to arrive Ok(wctx.wait()?) } #[deprecated(since = "0.10.2", note = "Use req() instead.")] pub fn send(&self, out: S) -> Result<R, Error<E>> { self.req(out) } /// Same as [`Client::req()`] but for use in `async` contexts. pub async fn areq(&self, out: S) -> Result<R, Error<E>> { let (sctx, wctx) = swctx::mkpair(); self .qpusher .push(ServerQueueNode { msg: out, reply: sctx }) .map_err(|_| Error::ServerDisappeared)?; Ok(wctx.wait_async().await?) } #[deprecated(since = "0.10.2", note = "Use areq() instead.")] pub async fn asend(&self, out: S) -> Result<R, Error<E>> { self.areq(out).await } } |
︙ | ︙ |
Changes to src/err.rs.
1 2 3 4 5 6 7 8 | use std::fmt; /// Module-specific error codes. #[derive(Debug)] pub enum Error<E> { /// The server object has shut down. /// /// Happens when clients: | > > | 1 2 3 4 5 6 7 8 9 10 | use std::fmt; use crate::rctx::RCtxState; /// Module-specific error codes. #[derive(Debug)] pub enum Error<E> { /// The server object has shut down. /// /// Happens when clients: |
︙ | ︙ | |||
48 49 50 51 52 53 54 | _ => panic!("Not an Error::App") } } } impl<E: fmt::Debug> std::error::Error for Error<E> {} | < < < < < < < < < < > > > > > > > > > > > > | 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | _ => panic!("Not an Error::App") } } } impl<E: fmt::Debug> std::error::Error for Error<E> {} impl<E: fmt::Debug> fmt::Display for Error<E> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { Error::ServerDisappeared => write!(f, "Server disappeared"), Error::ClientsDisappeared => write!(f, "Clients disappeared"), Error::NoReply => write!(f, "Server didn't reply"), Error::App(err) => write!(f, "Application error; {:?}", err) } } } impl<E> From<swctx::Error<RCtxState, E>> for Error<E> { fn from(err: swctx::Error<RCtxState, E>) -> Self { match err { swctx::Error::Aborted(state) => match state { RCtxState::Queued => Error::ServerDisappeared, RCtxState::Active => Error::NoReply }, swctx::Error::App(e) => Error::App(e) } } } // vim: set ft=rust et sw=2 ts=2 sts=2 cinoptions=2 tw=79 : |
Changes to src/rctx.rs.
1 2 3 4 5 6 7 | //! Allow a thread/task, crossing sync/async boundaries in either direction, to //! deliver an expected piece of data to another thread/task, with //! notification. //! //! These are simple channels used to deliver data from one endpoint to //! another, where the receiver will block until data has been delivered. | | | > > > > > | | > > > > > > | > > > > > > > > > > > > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | > > > > > | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | //! Allow a thread/task, crossing sync/async boundaries in either direction, to //! deliver an expected piece of data to another thread/task, with //! notification. //! //! These are simple channels used to deliver data from one endpoint to //! another, where the receiver will block until data has been delivered. use crate::err::Error; #[derive(Clone, Default)] pub(crate) enum RCtxState { #[default] Queued, Active } pub struct ReplyContext<T, E>(swctx::SetCtx<T, RCtxState, E>); impl<T, E> ReplyContext<T, E> { /// Send a reply back to originating client. /// /// # Example /// ``` /// use std::thread; /// use ump::channel; /// /// let (server, client) = channel::<String, String, ()>(); /// let server_thread = thread::spawn(move || { /// let (data, rctx) = server.wait().unwrap(); /// let reply = format!("Hello, {}!", data); /// rctx.reply(reply).unwrap(); /// }); /// let msg = String::from("Client"); /// let reply = client.req(msg).unwrap(); /// assert_eq!(reply, "Hello, Client!"); /// server_thread.join().unwrap(); /// ``` /// /// # Semantics /// This call is safe to make after the server context has been released. pub fn reply(self, data: T) -> Result<(), Error<E>> { self.0.set(data); Ok(()) } /// Return an error to originating client. /// This will cause the calling client to return an error. The error passed /// in the `err` parameter will be wrapped in a `Error::App(err)`. /// /// # Example /// /// ``` /// use std::thread; /// use ump::{channel, Error}; /// /// #[derive(Debug, PartialEq)] /// enum MyError { /// SomeError(String) /// } /// /// let (server, client) = channel::<String, String, MyError>(); /// let server_thread = thread::spawn(move || { /// let (_, rctx) = server.wait().unwrap(); /// rctx.fail(MyError::SomeError("failed".to_string())).unwrap(); /// }); /// let msg = String::from("Client"); /// let reply = client.req(msg); /// match reply { /// Err(Error::App(MyError::SomeError(s))) => { /// assert_eq!(s, "failed"); /// } /// _ => { /// panic!("Unexpected return value"); /// } /// } /// server_thread.join().unwrap(); /// ``` /// /// # Semantics /// This call is safe to make after the server context has been released. pub fn fail(self, err: E) -> Result<(), Error<E>> { self.0.fail(err); Ok(()) } } impl<T, E> From<swctx::SetCtx<T, RCtxState, E>> for ReplyContext<T, E> { fn from(sctx: swctx::SetCtx<T, RCtxState, E>) -> Self { sctx.set_state(RCtxState::Active); ReplyContext(sctx) } } // vim: set ft=rust et sw=2 ts=2 sts=2 cinoptions=2 tw=79 : |
Deleted src/rctx/err.rs.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/rctx/inner.rs.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Deleted src/rctx/public.rs.
|
| < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < < |
Changes to src/server.rs.
|
| | < | > > | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | use crate::{ err::Error, rctx::{RCtxState, ReplyContext} }; pub(crate) struct ServerQueueNode<S, R, E> { /// Raw message being sent from the client to the server. pub(crate) msg: S, /// Keep track of data needed to share reply data. pub(crate) reply: swctx::SetCtx<R, RCtxState, E> } /// Representation of a server object. /// /// Each instantiation of a [`Server`] object represents an end-point which /// will be used to receive messages from connected [`Client`](crate::Client) /// objects. |
︙ | ︙ |
Changes to www/changelog.md.
1 2 3 4 5 6 7 8 9 10 11 12 | # Change Log ## [Unreleased] ### Added ### Changed - Include tests when publishing crate. - Bugfix: Use `err::Error` rather than `rctx::err::Error` in rctx::public, giving `ReplyContext::reply()` and `ReplyContext::fail()` the correct return types. | > > > > > > > | | > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | # Change Log ## [Unreleased] ### Added ### Changed ### Removed ## [0.12.0] - 2023-08-15 ### Changed - Include tests when publishing crate. - Bugfix: Use `err::Error` rather than `rctx::err::Error` in rctx::public, giving `ReplyContext::reply()` and `ReplyContext::fail()` the correct return types. - Use the `swctx` crate for sending back the reply rather than use a custom in-tree implementation. - Update `edition` to `2021` and `rust-version` to `1.56`. - Add `--generate-link-to-definition` to `rustdoc-args` in `Cargo.toml` ## [0.11.0] - 2023-07-29 ### Changed - Include tests when publishing crate. |
︙ | ︙ | |||
31 32 33 34 35 36 37 | - Add `send()`/`asend()` wrappers around the new `req()`/`areq()` methods with a deprecation notice. - Add a `dev-docs` feature to allow internal documentation notes to be included in generated documentation. ### Changed | | | 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | - Add `send()`/`asend()` wrappers around the new `req()`/`areq()` methods with a deprecation notice. - Add a `dev-docs` feature to allow internal documentation notes to be included in generated documentation. ### Changed - Rename `send()`/`asend()` to `req()`/`areq()`. ## [0.10.1] - 2023-07-27 ### Changed - Runtime dependencies: |
︙ | ︙ |
Changes to www/index.md.
1 2 3 4 5 6 7 8 9 10 11 12 13 | # Micro-Message Passing Library The _ump_ crate is a simple client/server message passing library for intra-process communication. Its primary purpose is to allow cross async/non-async communication (for both the server and client endpoints). ## Change log The details of changes can always be found in the timeline, but for a high-level view of changes between released versions there's a manually maintained [Change Log](./changelog.md). | > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | # Micro-Message Passing Library The _ump_ crate is a simple client/server message passing library for intra-process communication. Its primary purpose is to allow cross async/non-async communication (for both the server and client endpoints). ## Change log The details of changes can always be found in the timeline, but for a high-level view of changes between released versions there's a manually maintained [Change Log](./changelog.md). ## Project Status _ump_ is in _maintenance mode_; it is feature-complete, but will receive bugfixes and improvements to implementation/documentation. |