Skip to content

Commit

Permalink
DOCS: Comments about consensus concurrency control
Browse files Browse the repository at this point in the history
  • Loading branch information
aakoshh committed Apr 15, 2024
1 parent dc2d5ef commit e2474c3
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 1 deletion.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ processing of some requests by immediately returning a future that will be
executed on the caller's task. Although all requests are still received by
the application task, not all request processing needs to happen on the
application task.
At this level the developer must pay closer attention to utilising Tower
layers to control the concurrency of the individual services mentioned above.
In particular the `Consensus` service should be wrapped with
`ServiceBuilder::concurrency_limit` to avoid a potential reordering of
consensus message effects caused by concurrent execution.

3. At the highest level of complexity, application developers can implement
multiple distinct `Service`s and manually control synchronization of shared
Expand All @@ -65,4 +70,4 @@ services, etc.

[ABCI]: https://docs.tendermint.com/master/spec/abci/
[Tower]: https://docs.rs/tower
[svc]: https://docs.rs/tower/0.4.6/tower/trait.Service.html
[svc]: https://docs.rs/tower/0.4.6/tower/trait.Service.html
3 changes: 3 additions & 0 deletions examples/kvstore_34/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ async fn main() {
// Hand those components to the ABCI server, but customize request behavior
// for each category -- for instance, apply load-shedding only to mempool
// and info requests, but not to consensus requests.
// Note that this example use synchronous execution in `Service::call`, wrapping the end result in a ready future.
// If `Service::call` did the actual request handling inside the `async` block as well, then the `consensus` service
// below should be wrapped with a `ServiceBuilder::concurrency_limit` to avoid any unintended reordering of message effects.
let server_builder = Server::builder()
.consensus(consensus)
.snapshot(snapshot)
Expand Down
3 changes: 3 additions & 0 deletions examples/kvstore_37/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,9 @@ async fn main() {
// Hand those components to the ABCI server, but customize request behavior
// for each category -- for instance, apply load-shedding only to mempool
// and info requests, but not to consensus requests.
// Note that this example use synchronous execution in `Service::call`, wrapping the end result in a ready future.
// If `Service::call` did the actual request handling inside the `async` block as well, then the `consensus` service
// below should be wrapped with a `ServiceBuilder::concurrency_limit` to avoid any unintended reordering of message effects.
let server_builder = Server::builder()
.consensus(consensus)
.snapshot(snapshot)
Expand Down
3 changes: 3 additions & 0 deletions examples/kvstore_38/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,9 @@ async fn main() {
// Hand those components to the ABCI server, but customize request behavior
// for each category -- for instance, apply load-shedding only to mempool
// and info requests, but not to consensus requests.
// Note that this example use synchronous execution in `Service::call`, wrapping the end result in a ready future.
// If `Service::call` did the actual request handling inside the `async` block as well, then the `consensus` service
// below should be wrapped with a `ServiceBuilder::concurrency_limit` to avoid any unintended reordering of message effects.
let server_builder = Server::builder()
.consensus(consensus)
.snapshot(snapshot)
Expand Down
6 changes: 6 additions & 0 deletions src/buffer4/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ where
/// [`poll_ready`] but will not issue a [`call`], which prevents other senders from issuing new
/// requests.
///
/// # A note on the scope of `bound`
///
/// Note that `bound` will only limit the rate of the _submission_ of [Message]s to the [Worker],
/// not their _execution_. If the execution itself is asynchronous, concurrency should be further
/// controlled by applying an appropriate [tower::Layer] on the returned service component.
///
/// [`Poll::Ready`]: std::task::Poll::Ready
/// [`call`]: crate::Service::call
/// [`poll_ready`]: crate::Service::poll_ready
Expand Down

0 comments on commit e2474c3

Please sign in to comment.