1use std::{
2 pin::Pin,
3 task::{Context, Poll},
4};
5
6use crate::{
7 backend::{
8 Backend, BackendConfig, WireFormatBackend,
9 codec::Codec,
10 finalize::{Durable, Ephemeral},
11 },
12 error::BoxDynError,
13 task::{Task, builder::TaskBuilder},
14};
15use futures_channel::mpsc::SendError;
16use futures_core::Stream;
17use futures_sink::Sink;
18use futures_util::SinkExt;
19use futures_util::StreamExt;
20use futures_util::stream;
21
22#[derive(Debug, thiserror::Error)]
24#[non_exhaustive]
25pub enum TaskSinkError<PushError> {
26 #[error("Failed to push task: {0}")]
28 PushError(#[from] PushError),
29 #[error("Failed to encode/decode task: {0}")]
31 CodecError(BoxDynError),
32
33 #[error("Failed to send new task: {0}")]
35 SendError(SendError),
36}
37
38pub trait TaskSink<Args, Kind>: Backend {
66 fn start_send(self: Pin<&mut Self>, item: Task<Args>)
75 -> Result<(), TaskSinkError<Self::Error>>;
76
77 fn poll_ready(
88 self: Pin<&mut Self>,
89 cx: &mut Context<'_>,
90 ) -> Poll<Result<(), TaskSinkError<Self::Error>>>;
91
92 fn poll_flush(
100 self: Pin<&mut Self>,
101 cx: &mut Context<'_>,
102 ) -> Poll<Result<(), TaskSinkError<Self::Error>>>;
103
104 fn poll_close(
111 self: Pin<&mut Self>,
112 cx: &mut Context<'_>,
113 ) -> Poll<Result<(), TaskSinkError<Self::Error>>>;
114
115 fn push(
120 &mut self,
121 task: Args,
122 ) -> impl Future<Output = Result<(), TaskSinkError<Self::Error>>> + Send;
123
124 fn push_bulk(
129 &mut self,
130 tasks: Vec<Args>,
131 ) -> impl Future<Output = Result<(), TaskSinkError<Self::Error>>> + Send;
132
133 fn push_stream(
139 &mut self,
140 tasks: impl Stream<Item = Args> + Unpin + Send,
141 ) -> impl Future<Output = Result<(), TaskSinkError<Self::Error>>> + Send;
142
143 fn push_task(
148 &mut self,
149 task: Task<Args>,
150 ) -> impl Future<Output = Result<(), TaskSinkError<Self::Error>>> + Send;
151
152 fn push_all(
158 &mut self,
159 tasks: impl Stream<Item = Task<Args>> + Unpin + Send,
160 ) -> impl Future<Output = Result<(), TaskSinkError<Self::Error>>> + Send;
161}
162impl<Args, S, E, C> TaskSink<Args, Durable> for S
163where
164 S: Sink<Task<C::Compact>, Error = E>
165 + Unpin
166 + Backend<Error = E>
167 + WireFormatBackend<Codec = C>
168 + BackendConfig<Args = Args, Kind = Durable>
169 + Send,
170 Args: Send,
171 C::Compact: Send,
172 C: Codec<Args> + Clone + Send + Sync,
173 E: Send,
174 C::Error: std::error::Error + Send + Sync + 'static,
175{
176 fn start_send(
177 self: Pin<&mut Self>,
178 item: Task<Args>,
179 ) -> Result<(), TaskSinkError<Self::Error>> {
180 let codec = self.codec();
181 let task = item.try_map_args(|t| {
182 codec
183 .encode(&t)
184 .map_err(|e| TaskSinkError::CodecError(e.into()))
185 })?;
186 Sink::start_send(self, task).map_err(|e| TaskSinkError::PushError(e))
187 }
188
189 fn poll_ready(
190 self: Pin<&mut Self>,
191 cx: &mut Context<'_>,
192 ) -> Poll<Result<(), TaskSinkError<Self::Error>>> {
193 Sink::poll_ready(self, cx).map_err(|e| TaskSinkError::PushError(e))
194 }
195
196 fn poll_flush(
197 self: Pin<&mut Self>,
198 cx: &mut Context<'_>,
199 ) -> Poll<Result<(), TaskSinkError<Self::Error>>> {
200 Sink::poll_flush(self, cx).map_err(|e| TaskSinkError::PushError(e))
201 }
202
203 fn poll_close(
204 self: Pin<&mut Self>,
205 cx: &mut Context<'_>,
206 ) -> Poll<Result<(), TaskSinkError<Self::Error>>> {
207 Sink::poll_close(self, cx).map_err(|e| TaskSinkError::PushError(e))
208 }
209 async fn push(&mut self, task: Args) -> Result<(), TaskSinkError<Self::Error>> {
210 use futures_util::SinkExt;
211 let encoded = self
212 .codec()
213 .encode(&task)
214 .map_err(|e| TaskSinkError::CodecError(e.into()))?;
215 self.send(TaskBuilder::new(encoded).build()).await?;
216 Ok(())
217 }
218
219 async fn push_bulk(&mut self, tasks: Vec<Args>) -> Result<(), TaskSinkError<Self::Error>> {
220 use futures_util::SinkExt;
221 let tasks = tasks
222 .into_iter()
223 .map(TaskBuilder::new)
224 .map(|task| {
225 task.try_map_args(|t| {
226 self.codec()
227 .encode(&t)
228 .map_err(|e| TaskSinkError::CodecError(e.into()))
229 })
230 .map(|t| t.build())
231 })
232 .collect::<Result<Vec<_>, _>>()?;
233 self.send_all(&mut stream::iter(tasks.into_iter().map(Ok)))
234 .await?;
235 Ok(())
236 }
237
238 async fn push_stream(
239 &mut self,
240 tasks: impl Stream<Item = Args> + Unpin + Send,
241 ) -> Result<(), TaskSinkError<Self::Error>> {
242 let codec = self.codec().clone();
243 self.sink_map_err(|e| TaskSinkError::PushError(e))
244 .send_all(&mut tasks.map(TaskBuilder::new).map(|task| {
245 task.try_map_args(|t| {
246 codec
247 .encode(&t)
248 .map_err(|e| TaskSinkError::CodecError(e.into()))
249 })
250 .map(|t| t.build())
251 }))
252 .await
253 }
254
255 async fn push_task(&mut self, task: Task<Args>) -> Result<(), TaskSinkError<Self::Error>> {
256 use futures_util::SinkExt;
257 let codec = self.codec();
258 let task = task.try_map_args(|t| {
259 codec
260 .encode(&t)
261 .map_err(|e| TaskSinkError::CodecError(e.into()))
262 })?;
263 self.sink_map_err(|e| TaskSinkError::PushError(e))
264 .send(task)
265 .await
266 }
267
268 async fn push_all(
269 &mut self,
270 tasks: impl Stream<Item = Task<Args>> + Unpin + Send,
271 ) -> Result<(), TaskSinkError<Self::Error>> {
272 use futures_util::SinkExt;
273 let codec = self.codec().clone();
274 let mut encoded = tasks.map(|task| {
275 task.try_map_args(|t| {
276 codec
277 .encode(&t)
278 .map_err(|e| TaskSinkError::CodecError(e.into()))
279 })
280 });
281 self.sink_map_err(|e| TaskSinkError::PushError(e))
282 .send_all(&mut encoded)
283 .await
284 }
285}
286
287impl<Args, S, E> TaskSink<Args, Ephemeral> for S
288where
289 S: Sink<Task<Args>, Error = E>
290 + Unpin
291 + Backend<Error = E>
292 + BackendConfig<Args = Args, Kind = Ephemeral>
293 + Send,
294 Args: Send,
295 E: Send,
296{
297 fn start_send(
298 self: Pin<&mut Self>,
299 item: Task<Args>,
300 ) -> Result<(), TaskSinkError<Self::Error>> {
301 Sink::start_send(self, item).map_err(|e| TaskSinkError::PushError(e))
302 }
303 fn poll_ready(
304 self: Pin<&mut Self>,
305 cx: &mut Context<'_>,
306 ) -> Poll<Result<(), TaskSinkError<Self::Error>>> {
307 Sink::poll_ready(self, cx).map_err(|e| TaskSinkError::PushError(e))
308 }
309
310 fn poll_flush(
311 self: Pin<&mut Self>,
312 cx: &mut Context<'_>,
313 ) -> Poll<Result<(), TaskSinkError<Self::Error>>> {
314 Sink::poll_flush(self, cx).map_err(|e| TaskSinkError::PushError(e))
315 }
316
317 fn poll_close(
318 self: Pin<&mut Self>,
319 cx: &mut Context<'_>,
320 ) -> Poll<Result<(), TaskSinkError<Self::Error>>> {
321 Sink::poll_close(self, cx).map_err(|e| TaskSinkError::PushError(e))
322 }
323
324 async fn push(&mut self, args: Args) -> Result<(), TaskSinkError<Self::Error>> {
325 let task = TaskBuilder::new(args).build();
326 self.send(task)
327 .await
328 .map_err(|e| TaskSinkError::PushError(e))
329 }
330
331 async fn push_bulk(&mut self, tasks: Vec<Args>) -> Result<(), TaskSinkError<Self::Error>> {
332 let tasks = tasks
333 .into_iter()
334 .map(TaskBuilder::new)
335 .map(|t| Ok::<_, E>(t.build()))
336 .collect::<Result<Vec<_>, _>>()?;
337 self.send_all(&mut stream::iter(tasks.into_iter().map(Ok)))
338 .await
339 .map_err(|e| TaskSinkError::PushError(e))?;
340 Ok(())
341 }
342
343 async fn push_stream(
344 &mut self,
345 tasks: impl Stream<Item = Args> + Unpin + Send,
346 ) -> Result<(), TaskSinkError<Self::Error>> {
347 self.sink_map_err(|e| TaskSinkError::PushError(e))
348 .send_all(&mut tasks.map(TaskBuilder::new).map(|task| Ok(task.build())))
349 .await
350 }
351
352 async fn push_task(&mut self, task: Task<Args>) -> Result<(), TaskSinkError<Self::Error>> {
353 use futures_util::SinkExt;
354 self.sink_map_err(|e| TaskSinkError::PushError(e))
355 .send(task)
356 .await
357 }
358
359 async fn push_all(
360 &mut self,
361 tasks: impl Stream<Item = Task<Args>> + Unpin + Send,
362 ) -> Result<(), TaskSinkError<Self::Error>> {
363 use futures_util::SinkExt;
364
365 self.sink_map_err(|e| TaskSinkError::PushError(e))
366 .send_all(&mut tasks.map(Ok))
367 .await
368 }
369}