reifydb_runtime/actor/mailbox/
mod.rs1#[cfg(all(reifydb_single_threaded, not(reifydb_dst)))]
5use std::cell::{Cell, RefCell};
6use std::fmt;
7#[cfg(all(reifydb_single_threaded, not(reifydb_dst)))]
8use std::rc::Rc;
9#[cfg(all(reifydb_single_threaded, not(reifydb_dst)))]
10use std::sync::Arc;
11#[cfg(all(reifydb_single_threaded, not(reifydb_dst)))]
12use std::sync::atomic::AtomicBool;
13
14use cfg_if::cfg_if;
15
16#[cfg(not(reifydb_single_threaded))]
17pub(crate) mod host;
18
19#[cfg(all(reifydb_single_threaded, not(reifydb_dst)))]
20pub(crate) mod wasm;
21
22#[cfg(reifydb_dst)]
23pub(crate) mod dst;
24
25cfg_if! {
26 if #[cfg(reifydb_dst)] {
27 type ActorRefInnerImpl<M> = dst::ActorRefInner<M>;
28 } else if #[cfg(not(reifydb_single_threaded))] {
29 type ActorRefInnerImpl<M> = host::ActorRefInner<M>;
30 } else {
31 type ActorRefInnerImpl<M> = wasm::ActorRefInner<M>;
32 }
33}
34
35#[derive(Debug, Clone, PartialEq, Eq)]
36pub enum SendError<M> {
37 Closed(M),
38
39 Full(M),
40}
41
42impl<M> SendError<M> {
43 #[inline]
44 pub fn into_inner(self) -> M {
45 match self {
46 SendError::Closed(m) => m,
47 SendError::Full(m) => m,
48 }
49 }
50}
51
52impl<M: fmt::Debug> fmt::Display for SendError<M> {
53 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54 match self {
55 SendError::Closed(_) => write!(f, "actor mailbox closed"),
56 SendError::Full(_) => write!(f, "actor mailbox full"),
57 }
58 }
59}
60
61impl<M: fmt::Debug> error::Error for SendError<M> {}
62
63#[derive(Debug, Clone, PartialEq, Eq)]
64pub enum AskError {
65 SendFailed,
66
67 ResponseClosed,
68}
69
70impl fmt::Display for AskError {
71 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72 match self {
73 AskError::SendFailed => write!(f, "failed to send ask request"),
74 AskError::ResponseClosed => write!(f, "response channel closed"),
75 }
76 }
77}
78
79impl error::Error for AskError {}
80
81#[derive(Debug, Clone, Copy, PartialEq, Eq)]
82pub enum TryRecvError {
83 Empty,
84
85 Closed,
86}
87
88#[derive(Debug, Clone, Copy, PartialEq, Eq)]
89pub enum RecvError {
90 Closed,
91}
92
93#[derive(Debug, Clone, Copy, PartialEq, Eq)]
94pub enum RecvTimeoutError {
95 Timeout,
96
97 Closed,
98}
99
100pub struct ActorRef<M> {
101 inner: ActorRefInnerImpl<M>,
102}
103
104impl<M> Clone for ActorRef<M> {
105 #[inline]
106 fn clone(&self) -> Self {
107 Self {
108 inner: self.inner.clone(),
109 }
110 }
111}
112
113impl<M> fmt::Debug for ActorRef<M> {
114 #[inline]
115 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
116 self.inner.fmt(f)
117 }
118}
119
120#[cfg(reifydb_single_threaded)]
123unsafe impl<M> Send for ActorRef<M> {}
124
125#[cfg(reifydb_single_threaded)]
126unsafe impl<M> Sync for ActorRef<M> {}
127
128impl<M> ActorRef<M> {
129 #[inline]
130 pub(crate) fn from_inner(inner: ActorRefInnerImpl<M>) -> Self {
131 Self {
132 inner,
133 }
134 }
135}
136
137#[cfg(not(reifydb_single_threaded))]
138impl<M: Send> ActorRef<M> {
139 #[inline]
140 pub(crate) fn new(tx: Sender<M>) -> Self {
141 Self {
142 inner: host::ActorRefInner::new(tx),
143 }
144 }
145
146 #[inline]
147 pub(crate) fn set_notify(&self, f: sync::Arc<dyn Fn() + Send + Sync>) {
148 self.inner.set_notify(f)
149 }
150
151 #[inline]
152 pub fn send(&self, msg: M) -> Result<(), SendError<M>> {
153 self.inner.send(msg)
154 }
155
156 #[inline]
157 pub fn send_blocking(&self, msg: M) -> Result<(), SendError<M>> {
158 self.inner.send_blocking(msg)
159 }
160
161 #[inline]
162 pub fn is_alive(&self) -> bool {
163 self.inner.is_alive()
164 }
165}
166
167#[cfg(reifydb_dst)]
168impl<M> ActorRef<M> {
169 #[inline]
170 pub fn send(&self, msg: M) -> Result<(), SendError<M>> {
171 self.inner.send(msg)
172 }
173
174 #[inline]
175 pub fn send_blocking(&self, msg: M) -> Result<(), SendError<M>> {
176 self.inner.send_blocking(msg)
177 }
178
179 #[inline]
180 pub fn is_alive(&self) -> bool {
181 self.inner.is_alive()
182 }
183
184 #[inline]
185 pub(crate) fn mark_stopped(&self) {
186 self.inner.mark_stopped()
187 }
188
189 #[inline]
190 pub(crate) fn set_notify(&self, f: Box<dyn Fn()>) {
191 self.inner.set_notify(f)
192 }
193}
194
195#[cfg(all(reifydb_single_threaded, not(reifydb_dst)))]
196impl<M> ActorRef<M> {
197 #[inline]
198 pub(crate) fn new(
199 processor: Rc<RefCell<Option<Box<dyn FnMut(M)>>>>,
200 alive: Arc<AtomicBool>,
201 queue: Rc<RefCell<Vec<M>>>,
202 processing: Rc<Cell<bool>>,
203 ) -> Self {
204 Self {
205 inner: wasm::ActorRefInner::new(processor, alive, queue, processing),
206 }
207 }
208
209 #[inline]
210 pub(crate) fn from_wasm_inner(
211 processor: Rc<RefCell<Option<Box<dyn FnMut(M)>>>>,
212 alive: Arc<AtomicBool>,
213 queue: Rc<RefCell<Vec<M>>>,
214 processing: Rc<Cell<bool>>,
215 ) -> Self {
216 Self {
217 inner: wasm::ActorRefInner::new(processor, alive, queue, processing),
218 }
219 }
220
221 #[inline]
222 pub fn send(&self, msg: M) -> Result<(), SendError<M>> {
223 self.inner.send(msg)
224 }
225
226 #[inline]
227 pub fn send_blocking(&self, msg: M) -> Result<(), SendError<M>> {
228 self.inner.send_blocking(msg)
229 }
230
231 #[inline]
232 pub fn is_alive(&self) -> bool {
233 self.inner.is_alive()
234 }
235
236 #[inline]
237 pub(crate) fn mark_stopped(&self) {
238 self.inner.mark_stopped()
239 }
240
241 #[inline]
242 pub(crate) fn processor(&self) -> &Rc<RefCell<Option<Box<dyn FnMut(M)>>>> {
243 &self.inner.processor
244 }
245}
246
247use std::error;
248#[cfg(not(reifydb_single_threaded))]
249use std::sync;
250
251#[cfg(not(reifydb_single_threaded))]
252use crossbeam_channel::Sender;
253#[cfg(reifydb_dst)]
254pub(crate) use dst::create_mailbox as create_dst_mailbox;
255#[cfg(not(reifydb_single_threaded))]
256pub(crate) use host::create_mailbox;
257#[cfg(all(reifydb_single_threaded, not(reifydb_dst)))]
258pub(crate) use wasm::create_actor_ref;