Skip to main content

RetriableMessage

Struct RetriableMessage 

Source
pub struct RetriableMessage<TKey, TMessage>
where TKey: JobKey, TMessage: Message,
{ pub key: TKey, pub message: Option<TMessage>, pub strategy: MessageRetryStrategy, pub retry_hook: Option<Arc<dyn Fn(&TKey) + Send + Sync + RefUnwindSafe>>, /* private fields */ }
Expand description

A retriable message is a job message which will automatically be resubmitted to the factory in the event of a factory worker dropping the message due to failure (panic or unhandled error). This wraps the inner message in a struct which captures the drop, and if there’s still some retries left, will reschedule the work to the factory with captured state information.

IMPORTANT CAVEATS:

  1. Regular loadshed events will cause this message to be retried if there is still retries left and the job isn’t expired unless you explicitely call completed() in the discard handler.
  2. Consumable types are not well supported here without some wrapping in Option types, which is because the value is handled everywhere as &mut ref due to the drop implementation requiring that it be so. This means that RPCs using crate::concurrency::oneshots likely won’t work without some real painful ergonomics.
  3. Upon successful handling of the job, you need to mark it as completed() at the end of your handling or discarding logic to state that it shouldn’t be retried on drop.

Fields§

§key: TKey

The key to the retriable job

§message: Option<TMessage>

The message, which will be retried until it’s completed.

§strategy: MessageRetryStrategy

The retry strategy

§retry_hook: Option<Arc<dyn Fn(&TKey) + Send + Sync + RefUnwindSafe>>

A function which will be executed upon the job’s retry flow being executed (helpful for logging, etc)

SAFETY: We utilize std::panic::catch_unwind here to best-effort prevent a potential user-level panic from causing a process abort. However if the handler logic panics, then the retry hook won’t be executed, but the job will still be retried.

Implementations§

Source§

impl<TKey, TMessage> RetriableMessage<TKey, TMessage>
where TKey: JobKey, TMessage: Message,

Source

pub fn new( key: TKey, message: TMessage, strategy: MessageRetryStrategy, ) -> RetriableMessage<TKey, TMessage>

Construct a new retriable message with the provided number of retries. If the retries are None, that means retry forever. [Some(0)] will mean no retries

Source

pub fn set_retry_hook( &mut self, f: impl Fn(&TKey) + Send + Sync + RefUnwindSafe + 'static, )

Attach a handler which will be executed when the job is retried (resubmitted to the factory).

Source

pub fn from_job( _: Job<TKey, TMessage>, strategy: MessageRetryStrategy, factory: ActorRef<FactoryMessage<TKey, RetriableMessage<TKey, TMessage>>>, ) -> Job<TKey, RetriableMessage<TKey, TMessage>>

Convert a regular Job into a RetriableMessage capturing all the necessary state in order to perform retries on drop.

  • job: The Job to convert
  • strategy: The MessageRetryStrategy to use for this retriable message
  • factory: The ActorRef of the factory which the job will be submitted to.

Returns a Job with message payload of RetriableMessage which can be retried should it be dropped prior to having job.msg.completed() called.

Source

pub fn capture_retry_state( &mut self, options: &JobOptions, factory: ActorRef<FactoryMessage<TKey, RetriableMessage<TKey, TMessage>>>, )

Capture the necessary state information in order to perform retries automatically

  • options: The JobOptions of the original job
  • factory: The ActorRef of the factory the job will be submitted to
Source

pub fn completed(&mut self)

Mark this message to not be retried upon being dropped, since it was handled successfully.

IMPORTANT: This should be called at the end of the handling logic, prior to returning from the worker’s message handler AND/OR from the discard logic. If you don’t provide a custom discard handler for jobs, then they will be auto-retried until a potential TTL is hit (or forever) and you may risk a spin-lock where an TTL expired job is submitted back to the factory, expire shedded again, dropped, and therefore retried forever. This is especially dangerous if you state that jobs should be retried forever.

Trait Implementations§

Source§

impl<TKey, TMsg> Debug for RetriableMessage<TKey, TMsg>
where TKey: JobKey, TMsg: Message,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl<TKey, TMessage> Drop for RetriableMessage<TKey, TMessage>
where TKey: JobKey, TMessage: Message,

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl<TKey, TMessage> Freeze for RetriableMessage<TKey, TMessage>
where TKey: Freeze, TMessage: Freeze,

§

impl<TKey, TMessage> !RefUnwindSafe for RetriableMessage<TKey, TMessage>

§

impl<TKey, TMessage> Send for RetriableMessage<TKey, TMessage>

§

impl<TKey, TMessage> Sync for RetriableMessage<TKey, TMessage>
where TMessage: Sync,

§

impl<TKey, TMessage> Unpin for RetriableMessage<TKey, TMessage>
where TKey: Unpin, TMessage: Unpin,

§

impl<TKey, TMessage> !UnwindSafe for RetriableMessage<TKey, TMessage>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Message for T
where T: Any + Send + 'static,

Source§

fn from_boxed(m: BoxedMessage) -> Result<Self, BoxedDowncastErr>

Convert a BoxedMessage to this concrete type
Source§

fn box_message(self, pid: &ActorId) -> Result<BoxedMessage, BoxedDowncastErr>

Convert this message to a BoxedMessage
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> State for T
where T: Any + Send + 'static,