8 releases

1.0.0-rc.5 Feb 12, 2024
0.8.1 Jan 29, 2021
0.2.7 Oct 12, 2020
0.2.6 Sep 18, 2020
0.0.7 Jan 15, 2020

#279 in Magic Beans

Download history 34/week @ 2023-10-31 20/week @ 2023-11-07 30/week @ 2023-11-14 24/week @ 2023-11-21 34/week @ 2023-11-28 20/week @ 2023-12-05 22/week @ 2023-12-12 19/week @ 2023-12-19 34/week @ 2023-12-26 8/week @ 2024-01-02 16/week @ 2024-01-09 42/week @ 2024-01-16 9/week @ 2024-01-23 24/week @ 2024-01-30 64/week @ 2024-02-06 99/week @ 2024-02-13

205 downloads per month
Used in 5 crates (4 directly)


986 lines

Tari Service framework


Service framework

This module contains the building blocks for async services.

It consists of the following modules:


This module contains the ServiceInitializer trait. Service modules should implement this trait and pass that implementation to the StackBuilder.


Contains the StackBuilder that is responsible for collecting and 'executing' the implementations of ServiceInitializer.


A set of utilities used to collect and share handles between services. The StackBuilder is responsible for initializing a ServiceHandlesFuture and making it available to ServiceInitializer implementations.

Handles are simply a way to communicate with their corresponding service. Typically, a SenderService would be used for this purpose but a handle can be implemented in any way the implementor sees fit.


This provides for query messages to be sent to services along with a "reply channel" for the service to send back results. The reply_channel::unbounded function is used to create a sender/receiver pair. The sender implements tower_service::Service and can be used to make requests of a applicable type. The receiver implements futures::Stream and will provide a RequestContext object that contains a oneshot reply channel that the service can use to reply back to the caller.



use tari_service_framework::{reply_channel, tower::ServiceExt};

block_on(async {
    let (mut sender, mut receiver) = reply_channel::unbounded();

    let (result, _) = futures::join!(
        // Make the request and make progress on the resulting future
        // At the same time receive the request and reply
        async move {
            let req_context = receiver.next().await.unwrap();
            let msg = req_context.request().clone();

    assert_eq!(result.unwrap(), "UPPER");


~83K SLoC