pub struct JetStreamPublisher { /* private fields */ }Expand description
The live JetStream publisher. Cheap to clone.
Every publish waits for the stream’s acknowledgement, so a rejected message (unknown stream,
violated expectation, storage failure) is an error rather than a silent drop. Like the Core
publisher it aliases the connection and may outlive it: after the broker shuts down every
publish reports NatsError::Closed.
A service reaches one wherever a mount site names JetStreamPublish: a reply, an Out slot,
or a startup hook that publishes outside any delivery.
§Examples
use std::io;
use ruststream::OutgoingMessage;
use ruststream_nats::prelude::*;
use serde::{Deserialize, Serialize};
#[derive(Deserialize)]
struct Order {
id: u64,
}
#[derive(Serialize, Outgoing)]
#[outgoing(name = "confirmations")]
struct Confirmation {
id: u64,
}
#[derive(Serialize, Outgoing)]
#[outgoing(name = "archive.orders")]
struct Archived {
id: u64,
}
#[derive(OutSlot)]
#[publishes(Archived)]
struct Archive;
#[subscriber(JetStreamSubject::new("orders.*", "ORDERS").durable("confirmer"), reply)]
async fn confirm(order: &Order) -> Confirmation {
Confirmation { id: order.id }
}
#[subscriber(JetStreamSubject::new("orders.*", "ORDERS").durable("archiver"))]
async fn archive(
order: &Order,
Out(out): Out<impl Publisher<Options = JetStreamOptions>, Archive>,
) -> HandlerOutcome {
let archived = Archived { id: order.id };
if out
.message(&archived)
.message_id(format!("order-{}", order.id))
.publish()
.await
.is_err()
{
return HandlerOutcome::retry();
}
HandlerOutcome::ack()
}
#[ruststream::app]
fn app() -> impl App {
RustStream::new(AppInfo::new("orders", "0.1.0")).with_broker(
NatsBroker::new("nats://localhost:4222"),
|b| {
b.include(confirm)
.out_reply(JetStreamPublish::default().expect_stream("CONFIRMATIONS"));
b.include(archive)
.out(Archive, JetStreamPublish::default().expect_stream("ARCHIVE"))
.build();
b.after_startup(
JetStreamPublish::default().expect_stream("ORDERS"),
async move |publisher| -> io::Result<()> {
let ack = publisher
.publish_ack(OutgoingMessage::new("orders.created", br#"{"id":1}"#), None)
.await
.map_err(io::Error::other)?;
tracing::info!(stream = %ack.stream, ack.sequence, "seeded");
Ok(())
},
);
},
)
}Implementations§
Source§impl JetStreamPublisher
impl JetStreamPublisher
Sourcepub async fn publish_ack(
&self,
msg: OutgoingMessage<'_, BytesMut>,
options: Option<&JetStreamOptions>,
) -> Result<PublishAck, NatsError>
pub async fn publish_ack( &self, msg: OutgoingMessage<'_, BytesMut>, options: Option<&JetStreamOptions>, ) -> Result<PublishAck, NatsError>
Publishes into the stream and returns the acknowledgement: the stream the message landed in, its sequence there, and whether the deduplication window recognised it as a duplicate.
Publisher::publish is this call with the acknowledgement discarded. options is what
this one message states about itself; pass None to publish on the policy alone.
§Errors
Returns NatsError::Closed when the broker has shut down, NatsError::Publish when
the message cannot be sent, and NatsError::JetStream when the stream rejects it (no
such stream, or an expectation did not hold).
§Cancel safety
Not cancel-safe: dropping the future after the message is on the wire abandons the acknowledgement, leaving the publish in an indeterminate state.
Trait Implementations§
Source§impl Clone for JetStreamPublisher
impl Clone for JetStreamPublisher
Source§impl Debug for JetStreamPublisher
impl Debug for JetStreamPublisher
Source§impl Publisher for JetStreamPublisher
impl Publisher for JetStreamPublisher
Source§type Payload = Take
type Payload = Take
The same answer the Core publisher gives: a JetStream publish carries a Bytes the
client keeps.
Source§async fn publish(
&self,
msg: OutgoingMessage<'_, BytesMut>,
options: Option<&Self::Options>,
) -> Result<(), Self::Error>
async fn publish( &self, msg: OutgoingMessage<'_, BytesMut>, options: Option<&Self::Options>, ) -> Result<(), Self::Error>
§Cancel safety
Not cancel-safe; see publish_ack.
Source§type Options = JetStreamOptions
type Options = JetStreamOptions
QoS, a priority, an ordering key, whatever this
transport lets one message differ from the next in. Read moreAuto Trait Implementations§
impl !RefUnwindSafe for JetStreamPublisher
impl !UnwindSafe for JetStreamPublisher
impl Freeze for JetStreamPublisher
impl Send for JetStreamPublisher
impl Sync for JetStreamPublisher
impl Unpin for JetStreamPublisher
impl UnsafeUnpin for JetStreamPublisher
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
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 moreSource§impl<P> PublishExt for P
impl<P> PublishExt for P
Source§fn message<'a, T>(
&'a self,
value: &'a T,
) -> PublishBuilder<&'a Self, MessageBody<'a, T>, UnnamedCodec, HeadersUnset, <T as OutgoingDestination>::Form>where
T: OutgoingDestination,
fn message<'a, T>(
&'a self,
value: &'a T,
) -> PublishBuilder<&'a Self, MessageBody<'a, T>, UnnamedCodec, HeadersUnset, <T as OutgoingDestination>::Form>where
T: OutgoingDestination,
#[derive(Outgoing)] value, encoded with the crate’s
default codec (name another one with with_codec(..)). A
Serialized value’s bytes leave as they are instead - the wire is
the type’s own (MessageWire), and no codec runs on it. Read moreSource§fn begin(
&self,
) -> impl Future<Output = Result<TransactionScope<'_, Self, UnnamedCodec, AnyDeclared>, Self::Error>> + Sendwhere
Self: Sized + TransactionalPublisher,
fn begin(
&self,
) -> impl Future<Output = Result<TransactionScope<'_, Self, UnnamedCodec, AnyDeclared>, Self::Error>> + Sendwhere
Self: Sized + TransactionalPublisher,
TransactionScope that
owns it. Read moreSource§fn owned_transaction(
&self,
) -> impl Future<Output = Result<TypedTransaction<Self::Transaction, UnnamedCodec, AnyDeclared>, Self::Error>> + Sendwhere
Self: Sized + OwnedTransactions,
fn owned_transaction(
&self,
) -> impl Future<Output = Result<TypedTransaction<Self::Transaction, UnnamedCodec, AnyDeclared>, Self::Error>> + Sendwhere
Self: Sized + OwnedTransactions,
TypedTransaction that owns it. Read more