Skip to main content

Publisher

Struct Publisher 

Source
pub struct Publisher<T: Pod> { /* private fields */ }
Expand description

The write side of a Photon SPMC channel.

There is exactly one Publisher per channel. It is Send but not Sync — only one thread may publish at a time (single-producer guarantee enforced by &mut self).

Implementations§

Source§

impl<T: Pod> Publisher<T>

Source

pub fn publish_with(&mut self, f: impl FnOnce() -> T)

Publish a value built by a closure.

The closure returns the value, so it cannot leave the payload partly initialised; it is built as a stack temporary and then written to the slot.

On a bounded channel (created with channel_bounded()), this method spin-waits until there is room in the ring, ensuring no message loss (same backpressure semantics as publish()). On a regular (lossy) channel, this publishes immediately.

§Example
let (mut p, s) = photon_ring::channel::<u64>(64);
let mut sub = s.subscribe();
p.publish_with(|| 42u64);
assert_eq!(sub.try_recv(), Ok(42));
Source

pub fn publish(&mut self, value: T)

Publish a single value. Zero-allocation, O(1).

On a bounded channel (created with channel_bounded()), this method spin-waits until there is room in the ring, ensuring no message loss. On a regular (lossy) channel, this publishes immediately without any backpressure check.

Source

pub fn try_publish(&mut self, value: T) -> Result<(), PublishError<T>>

Try to publish a single value with backpressure awareness.

  • On a regular (lossy) channel created with channel(), this always succeeds — it publishes the value and returns Ok(()).
  • On a bounded channel created with channel_bounded(), this checks whether the slowest subscriber has fallen too far behind. If publisher_seq - slowest_cursor >= capacity - watermark, it returns Err(PublishError::Full(value)) without writing.
Source

pub fn publish_batch(&mut self, values: &[T])

Publish a batch of values.

Both lossy and bounded channels advance the cursor per-value, so a subscribe() call concurrent with publication will only see messages published after the subscribe point (future-only contract).

On a bounded channel: spin-waits for room before each value, ensuring no message loss.

Source

pub fn published(&self) -> u64

Number of messages published so far, which is also the next sequence number to be written. Useful for computing lag: publisher.published() - subscriber.cursor.

Source

pub fn capacity(&self) -> u64

Ring capacity.

Source

pub fn mlock(&self) -> bool

Lock the ring buffer pages in RAM, preventing the OS from swapping them to disk. Reduces worst-case latency by eliminating page-fault stalls on the hot path.

Returns true on success. Requires CAP_IPC_LOCK or sufficient RLIMIT_MEMLOCK on Linux. No-op on other platforms.

Source

pub unsafe fn prefault(&self)

Pre-fault all ring buffer pages by writing a zero byte to each 4 KiB page. Ensures the first publish does not trigger a page fault.

§Safety

Must be called before any publish/subscribe operations begin. Calling this while the ring is in active use is undefined behavior because it writes zero bytes to live ring memory via raw pointers, which can corrupt slot data and seqlock stamps.

Trait Implementations§

Source§

impl<T: Pod> Send for Publisher<T>

Auto Trait Implementations§

§

impl<T> !RefUnwindSafe for Publisher<T>

§

impl<T> !Sync for Publisher<T>

§

impl<T> !UnwindSafe for Publisher<T>

§

impl<T> Freeze for Publisher<T>

§

impl<T> Unpin for Publisher<T>

§

impl<T> UnsafeUnpin for Publisher<T>

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, 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, 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.