Skip to main content

ed_journals/modules/fs/models/
async_blocker.rs

1pub mod async_unblocker;
2
3use crate::fs::models::async_blocker::async_unblocker::AsyncUnblocker;
4use crate::fs::traits::blocker::Blocker;
5use crate::fs::traits::unblocker::Unblocker;
6use crate::fs::{BlockResult, LogFSError};
7use futures::channel::mpsc::{Receiver, Sender};
8use futures::StreamExt;
9use std::sync::Arc;
10
11/// Blocker that can be used to block in async code.
12pub struct AsyncBlocker {
13    receiver: Receiver<BlockResult>,
14    sender: Sender<BlockResult>,
15}
16
17impl AsyncBlocker {
18    /// Create a new AsyncBlocker with the given capacity.
19    pub fn new(capacity: usize) -> AsyncBlocker {
20        let (sender, receiver) = futures::channel::mpsc::channel(capacity);
21
22        AsyncBlocker { sender, receiver }
23    }
24
25    /// Block and await the current task until a registered caller unblocks it.
26    pub async fn wait(&mut self) -> BlockResult {
27        self.receiver
28            .next()
29            .await
30            .ok_or(LogFSError::AsyncRecvError)?
31    }
32}
33
34impl Blocker for AsyncBlocker {
35    fn unblocker(&self) -> Arc<dyn Unblocker> {
36        Arc::new(AsyncUnblocker::new(self.sender.clone()))
37    }
38}
39
40impl From<AsyncBlocker> for Arc<dyn Unblocker> {
41    fn from(blocker: AsyncBlocker) -> Arc<dyn Unblocker> {
42        blocker.unblocker()
43    }
44}
45
46impl From<&AsyncBlocker> for Arc<dyn Unblocker> {
47    fn from(blocker: &AsyncBlocker) -> Arc<dyn Unblocker> {
48        blocker.unblocker()
49    }
50}