use bytes::Bytes;
use ruststream::{OutgoingMessage, OwnedTransactions, Transaction};
use tracing::warn;
use crate::error::AmqpError;
use crate::publisher::{Buffered, ConfirmsPublisher};
#[must_use = "a transaction does nothing until settled with commit() or abort()"]
pub struct ConfirmsTransaction {
publisher: ConfirmsPublisher,
buffered: Vec<Buffered>,
settled: bool,
}
impl std::fmt::Debug for ConfirmsTransaction {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ConfirmsTransaction")
.field("buffered", &self.buffered.len())
.field("settled", &self.settled)
.finish_non_exhaustive()
}
}
impl Drop for ConfirmsTransaction {
fn drop(&mut self) {
if !self.settled {
warn!(
target: "ruststream_lapin",
buffered = self.buffered.len(),
"owned transaction dropped without commit or abort; its buffered messages are \
discarded"
);
}
}
}
impl Transaction for ConfirmsTransaction {
type Error = AmqpError;
async fn publish(&mut self, msg: OutgoingMessage<'_>) -> Result<(), Self::Error> {
self.buffered.push((
msg.name().to_owned(),
Bytes::copy_from_slice(msg.payload()),
msg.headers().clone(),
));
Ok(())
}
async fn commit(mut self) -> Result<(), Self::Error> {
self.settled = true;
self.publisher.flush_owned(&self.buffered).await
}
async fn abort(mut self) -> Result<(), Self::Error> {
self.settled = true;
Ok(())
}
}
impl OwnedTransactions for ConfirmsPublisher {
type Transaction = ConfirmsTransaction;
async fn transaction(&self) -> Result<Self::Transaction, Self::Error> {
Ok(ConfirmsTransaction {
publisher: self.clone(),
buffered: Vec::new(),
settled: false,
})
}
}