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§
Required Methods§
sourcefn send(
&self,
msg: Self::Msg
) -> impl Future<Output = ProgressSendResult<()>> + Send
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.
sourcefn try_send(&self, msg: Self::Msg) -> ProgressSendResult<()>
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.
sourcefn blocking_send(&self, msg: Self::Msg) -> ProgressSendResult<()>
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§
sourcefn with_map<U: Send + Sync + 'static, F: Fn(U) -> Self::Msg + Send + Sync + Clone + 'static>(
self,
f: F
) -> WithMap<Self, U, F>
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.
sourcefn 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 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.
sourcefn boxed(self) -> BoxedProgressSender<Self::Msg>where
Self: IdGenerator,
fn boxed(self) -> BoxedProgressSender<Self::Msg>where
Self: IdGenerator,
Create a boxed progress sender to get rid of the concrete type.