// What a delivery is, what a result is, and the label a state writes on the wire.
///|
/// Where a task is in its life. The set is the one a caller has to be able to
/// tell apart, and it is the one published result stores agree on:
///
/// - `Pending` — accepted by a broker, not yet picked up.
/// - `Received` — a worker took it off the queue.
/// - `Started` — the body is running.
/// - `Retrying` — the body failed and the task is queued again.
/// - `Succeeded` — the body returned; the result is stored.
/// - `Failed` — the body raised on its last attempt; the error is stored.
/// - `Revoked` — cancelled before or during the run; it will not be sent again.
#derive(Eq, Debug)
pub(all) enum State {
Pending
Received
Started
Retrying
Succeeded
Failed
Revoked
}
///|
pub extend State with Eq::{not_equal, equal}
///|
pub extend State with Debug::{to_repr}
///|
/// The label a result store writes for a state. These are the labels the
/// published protocol uses, so a result written by another producer reads back
/// as the same state.
pub fn State::code(self : State) -> String {
match self {
Pending => "PENDING"
Received => "RECEIVED"
Started => "STARTED"
Succeeded => "SUCCESS"
Failed => "FAILURE"
Retrying => "RETRY"
Revoked => "REVOKED"
}
}
///|
/// The state a store's label names. An unknown label is refused rather than
/// read as `Pending`: a store that grew a state this library does not know is a
/// store this library must not guess about.
pub fn State::of(code : StringView) -> State raise Refused {
match code {
"PENDING" => Pending
"RECEIVED" => Received
"STARTED" => Started
"SUCCESS" => Succeeded
"FAILURE" => Failed
"RETRY" => Retrying
"REVOKED" => Revoked
_ => raise Refused::Unknown(name=code.to_owned())
}
}
///|
pub impl Show for State with fn output(self, logger) {
logger.write_string(self.code())
}
///|
pub extend State with Show::{to_string, output}
///|
/// Whether no further state will follow. A caller waiting for a result stops
/// here.
pub fn State::is_final(self : State) -> Bool {
match self {
Succeeded | Failed | Revoked => true
Pending | Received | Started | Retrying => false
}
}
///|
/// What a worker records when a run ends: the state it ended in, the value or
/// the error, and when.
///
/// `result` is the decoded return value of the body and `error` is the message
/// of the raised error; exactly one of them is set for a final state.
#derive(Eq, Debug)
pub(all) struct Outcome {
state : State
result : Json?
error : String?
retries : Int32
at : Int64
}
///|
pub extend Outcome with Eq::{not_equal, equal}
///|
pub extend Outcome with Debug::{to_repr}
///|
/// The outcome of a run that returned `value`.
pub fn outcome_succeeded(value : Json, retries : Int32, at : Int64) -> Outcome {
{ state: Succeeded, result: Some(value), error: None, retries, at, }
}
///|
/// The outcome of a run that raised `error` on attempt `retries`.
pub fn outcome_failed(error : String, retries : Int32, at : Int64) -> Outcome {
{ state: Failed, result: None, error: Some(error), retries, at, }
}
///|
/// What a broker hands a worker: one message, the queue it came from, and the
/// receipt the broker needs back to settle it.
///
/// `receipt` is opaque to this library. An in-memory broker puts a sequence
/// there, an ordered-log broker the id of the entry; whatever it is, the worker
/// only ever hands it back to the same broker.
#derive(Eq, Debug)
pub(all) struct Delivery {
message : Message
queue : String
receipt : String
}
///|
pub extend Delivery with Eq::{not_equal, equal}
///|
pub extend Delivery with Debug::{to_repr}
///|
/// What a broker reports about one of its queues.
///
/// `unacked` counts messages a worker holds and has not settled, which is the
/// number a dashboard shows next to the ready count so a stuck consumer is
/// visible.
#derive(Eq, Debug)
pub(all) struct QueueInfo {
name : String
ready : Int64
delayed : Int64
unacked : Int64
}
///|
pub extend QueueInfo with Eq::{not_equal, equal}
///|
pub extend QueueInfo with Debug::{to_repr}