#[non_exhaustive]pub enum OutboxError {
NoPool {
name: &'static str,
},
Record {
name: &'static str,
record: &'static str,
source: Error,
},
WriteLockHeld {
name: &'static str,
record: &'static str,
},
Recover {
name: &'static str,
record: &'static str,
source: Error,
},
Republish {
name: &'static str,
record: &'static str,
id: String,
source: Box<dyn StdError + Send + Sync>,
},
}Expand description
A failure of the outbox: a record it could not write or read, or a republish that did not reach the broker.
§Examples
use ruststream::runtime::PublishError;
use ruststream_sqlx::outbox::{OutboxError, TrackedPublishError};
pub async fn serve(pool: PgPool) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let tracking = outbox! { pool: pool, "orders" => OrderOutbox };
let broker = MemoryBroker::new().bindable();
let egress = broker.bind(Publish);
let running = RustStream::new(AppInfo::new("orders", "0.1.0"))
.with_broker(broker, |b| {
b.include(fulfil);
})
.start()
.await?;
let publisher = tracking.wrap(running.publisher(egress).await?);
// The status an HTTP endpoint answers an order with.
let status = match publisher.message(&OrderPlaced { id: 7 }).publish().await {
Ok(()) => 202,
// Recorded but not sent: the next startup sends it.
Err(PublishError::Publish(TrackedPublishError::Publish(_))) => 202,
// Neither recorded nor sent: the client sends the order again.
Err(PublishError::Publish(TrackedPublishError::Outbox(OutboxError::Record { .. }))) => 503,
Err(_) => 500,
};
tracing::info!(status, "order answered");
running.shutdown().await?;
Ok(())
}Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
NoPool
A message under a registered name was published before the outbox had a pool.
Record
The record of a published message was not written; the message was not sent.
Fields
WriteLockHeld
A transactional handler on SQLite published a message under a registered name while its own delivery transaction held the database’s write lock, which the record needs; the message was not sent.
The transaction holds the lock from its first write through Tx, or from its begin in an
immediate or exclusive mode, until the delivery settles. A transaction that took the lock as
it began fails the publish at once. After a statement through Tx the record waits for the
lock at most the pool’s acquire timeout, since SQLite tells whether that statement wrote
only by the wait. Such a handler publishes its tracked messages before its first write.
Recover
The unprocessed records of a name were not read at startup.
Fields
Republish
A record read at startup was not published again.
Trait Implementations§
Source§impl Debug for OutboxError
impl Debug for OutboxError
Source§impl Display for OutboxError
impl Display for OutboxError
Source§impl Error for OutboxError
impl Error for OutboxError
Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()
Auto Trait Implementations§
impl !RefUnwindSafe for OutboxError
impl !UnwindSafe for OutboxError
impl Freeze for OutboxError
impl Send for OutboxError
impl Sync for OutboxError
impl Unpin for OutboxError
impl UnsafeUnpin for OutboxError
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
impl<T, W> HasTypeWitness<W> for Twhere
W: MakeTypeWitness<Arg = T>,
T: ?Sized,
Source§impl<T> Identity for Twhere
T: ?Sized,
impl<T> Identity for Twhere
T: ?Sized,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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