Trait iroh_blobs::util::progress::ProgressSender

source ·
pub trait ProgressSender: Debug + Clone + Send + Sync + 'static {
    type Msg: Send + Sync + 'static;

    // Required methods
    fn send(
        &self,
        msg: Self::Msg
    ) -> impl Future<Output = ProgressSendResult<()>> + Send;
    fn try_send(&self, msg: Self::Msg) -> ProgressSendResult<()>;
    fn blocking_send(&self, msg: Self::Msg) -> ProgressSendResult<()>;

    // Provided methods
    fn with_map<U: Send + Sync + 'static, F: Fn(U) -> Self::Msg + Send + Sync + Clone + 'static>(
        self,
        f: F
    ) -> WithMap<Self, U, F> { ... }
    fn with_filter_map<U: Send + Sync + 'static, F: Fn(U) -> Option<Self::Msg> + Send + Sync + Clone + 'static>(
        self,
        f: F
    ) -> WithFilterMap<Self, U, F> { ... }
    fn boxed(self) -> BoxedProgressSender<Self::Msg>
       where Self: IdGenerator { ... }
}
Expand description

A general purpose progress sender. This should be usable for reporting progress from both blocking and non-blocking contexts.

§Id generation

Any good progress protocol will refer to entities by means of a unique id. E.g. if you want to report progress about some file operation, including details such as the full path of the file would be very wasteful. It is better to introduce a unique id for the file and then report progress using that id.

The IdGenerator trait provides a method to generate such ids, IdGenerator::new_id.

§Sending important messages

Some messages are important for the receiver to receive. E.g. start and end messages for some operation. If the receiver would miss one of these messages, it would lose the ability to make sense of the progress message stream.

This trait provides a method to send such important messages, in both blocking contexts where you have to block until the message is sent ProgressSender::blocking_send, and non-blocking contexts where you have to yield until the message is sent ProgressSender::send.

§Sending unimportant messages

Some messages are self-contained and not important for the receiver to receive. E.g. if you send millions of progress messages for copying a file that each contain an id and the number of bytes copied so far, it is not important for the receiver to receive every single one of these messages. In fact it is useful to drop some of these messages because waiting for the progress events to be sent can slow down the actual operation.

This trait provides a method to send such unimportant messages that can be used in both blocking and non-blocking contexts, ProgressSender::try_send.

§Errors

When the receiver is dropped, sending a message will fail. This provides a way for the receiver to signal that the operation should be stopped.

E.g. for a blocking copy operation that reports frequent progress messages, as soon as the receiver is dropped, this is a signal to stop the copy operation.

The error type is ProgressSendError, which can be converted to an std::io::Error for convenience.

§Transforming the message type

Sometimes you have a progress sender that sends a message of type A but an operation that reports progress of type B. If you have a transformation for every B to an A, you can use the ProgressSender::with_map method to transform the message.

This is similar to the futures::SinkExt::with method.

§Filtering the message type

Sometimes you have a progress sender that sends a message of enum A but an operation that reports progress of type B. You are interested only in some enum cases of A that can be transformed to B. You can use the ProgressSender::with_filter_map method to filter and transform the message.

§No-op progress sender

If you don’t want to report progress, you can use the IgnoreProgressSender type.

§Async channel progress sender

If you want to use an async channel, you can use the AsyncChannelProgressSender type.

§Implementing your own progress sender

Progress senders will frequently be used in a multi-threaded context.

They must be cheap to clone and send between threads. They must also be thread safe, which is ensured by the Send and Sync bounds. They must also be unencumbered by lifetimes, which is ensured by the 'static bound.

A typical implementation will wrap the sender part of a channel and an id generator.

Required Associated Types§

source

type Msg: Send + Sync + 'static

The message being sent.

Required Methods§

source

fn send( &self, msg: Self::Msg ) -> impl Future<Output = ProgressSendResult<()>> + Send

Send a message and wait if the receiver is full.

Use this to send important progress messages where delivery must be guaranteed.

source

fn try_send(&self, msg: Self::Msg) -> ProgressSendResult<()>

Try to send a message and drop it if the receiver is full.

Use this to send progress messages where delivery is not important, e.g. a self contained progress message.

source

fn blocking_send(&self, msg: Self::Msg) -> ProgressSendResult<()>

Send a message and block if the receiver is full.

Use this to send important progress messages where delivery must be guaranteed.

Provided Methods§

source

fn with_map<U: Send + Sync + 'static, F: Fn(U) -> Self::Msg + Send + Sync + Clone + 'static>( self, f: F ) -> WithMap<Self, U, F>

Transform the message type by mapping to the type of this sender.

source

fn with_filter_map<U: Send + Sync + 'static, F: Fn(U) -> Option<Self::Msg> + Send + Sync + Clone + 'static>( self, f: F ) -> WithFilterMap<Self, U, F>

Transform the message type by filter-mapping to the type of this sender.

source

fn boxed(self) -> BoxedProgressSender<Self::Msg>
where Self: IdGenerator,

Create a boxed progress sender to get rid of the concrete type.

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

source§

impl<T: Send + Sync + 'static> ProgressSender for Arc<dyn BoxableProgressSender<T>>

§

type Msg = T

source§

fn send(&self, msg: T) -> impl Future<Output = ProgressSendResult<()>> + Send

source§

fn try_send(&self, msg: T) -> ProgressSendResult<()>

source§

fn blocking_send(&self, msg: T) -> ProgressSendResult<()>

source§

impl<T: ProgressSender> ProgressSender for Option<T>

§

type Msg = <T as ProgressSender>::Msg

source§

async fn send(&self, msg: Self::Msg) -> ProgressSendResult<()>

source§

fn try_send(&self, msg: Self::Msg) -> ProgressSendResult<()>

source§

fn blocking_send(&self, msg: Self::Msg) -> ProgressSendResult<()>

Implementors§

source§

impl<I: ProgressSender, U: Send + Sync + 'static, F: Fn(U) -> Option<I::Msg> + Clone + Send + Sync + 'static> ProgressSender for WithFilterMap<I, U, F>

§

type Msg = U

source§

impl<I: ProgressSender, U: Send + Sync + 'static, F: Fn(U) -> I::Msg + Clone + Send + Sync + 'static> ProgressSender for WithMap<I, U, F>

§

type Msg = U

source§

impl<T: Send + Sync + 'static> ProgressSender for AsyncChannelProgressSender<T>

§

type Msg = T

source§

impl<T: Send + Sync + 'static> ProgressSender for BoxedProgressSender<T>

§

type Msg = T

source§

impl<T: Send + Sync + 'static> ProgressSender for IgnoreProgressSender<T>

§

type Msg = T