pub trait EventHandlerWithState<E, S>: Send {
// Required method
fn on_event(
&mut self,
state: &mut S,
event: &E,
sequence: Sequence,
end_of_batch: bool,
);
}Expand description
Trait for processing events with a separate mutable state value.
This is used by handle_events_and_state_with so handlers can be closures or dedicated structs,
without introducing dynamic dispatch.
§Why a separate state value?
Consumer threads are started with std::thread::spawn, which requires that anything moved into
the spawned thread is Send. That means the handler must be Send.
However, sometimes you want per-consumer state that is thread-scoped and therefore does not
need to be Send (for example, Rc, RefCell, or other single-threaded arenas/allocators).
You cannot store such a !Send value inside the handler struct itself, because then the handler
becomes !Send and cannot be moved into the consumer thread.
handle_events_and_state_with takes an initialize_state closure (which is Send) and calls
it inside the consumer thread after it starts, so the produced state can safely be !Send
as long as it never leaves that thread.
§Example: Rc<RefCell<_>> state
use std::{cell::RefCell, rc::Rc};
use disrupt_rs::{build_single_producer, BusySpin, Producer, Sequence};
#[derive(Default)]
struct State {
// `Rc` is `!Send`, so `State` is `!Send` too.
counter: Rc<RefCell<u64>>,
}
#[derive(Default)]
struct Event {
value: u64,
}
let mut producer = build_single_producer(64, Event::default, BusySpin)
.handle_events_and_state_with(
|state: &mut State, _event: &Event, _seq: Sequence, _end: bool| {
*state.counter.borrow_mut() += 1;
},
State::default, // constructed inside the consumer thread
)
.build();
producer.publish(|e| e.value = 123);
drop(producer);Required Methods§
Dyn Compatibility§
This trait is dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".