Skip to main content

chromiumoxide/handler/
sender.rs

1//! A thin wrapper around `mpsc::Sender<TargetMessage>` that optionally
2//! notifies the handler's `tokio::select!` loop when a message is sent.
3//!
4//! When `Handler::run()` is used (the tokio-native path), the contained
5//! `Notify` wakes the event loop so it can drain target channels
6//! immediately.  When the legacy `impl Stream for Handler` is used,
7//! the notify is `None` and the wrapper adds zero overhead.
8
9use std::sync::Arc;
10use tokio::sync::{mpsc, Notify};
11
12use super::target::TargetMessage;
13
14/// Sender half for page → target communication.
15///
16/// Wraps a bounded `mpsc::Sender<TargetMessage>` and, when running under
17/// `Handler::run()`, an `Arc<Notify>` that wakes the handler's
18/// `tokio::select!` loop after every successful send.
19#[derive(Debug, Clone)]
20pub struct PageSender {
21    inner: mpsc::Sender<TargetMessage>,
22    wake: Option<Arc<Notify>>,
23}
24
25impl PageSender {
26    /// Create a new `PageSender`.
27    ///
28    /// Pass `None` for `wake` when using the `Stream`-based handler
29    /// (no notification overhead). Pass `Some(notify)` when using
30    /// `Handler::run()`.
31    pub fn new(inner: mpsc::Sender<TargetMessage>, wake: Option<Arc<Notify>>) -> Self {
32        Self { inner, wake }
33    }
34
35    /// Notify the handler (if a `Notify` is configured).
36    #[inline]
37    fn notify(&self) {
38        if let Some(wake) = &self.wake {
39            wake.notify_one();
40        }
41    }
42
43    /// Non-blocking send.  Notifies the handler on success.
44    pub fn try_send(
45        &self,
46        msg: TargetMessage,
47    ) -> Result<(), mpsc::error::TrySendError<TargetMessage>> {
48        let result = self.inner.try_send(msg);
49        if result.is_ok() {
50            self.notify();
51        }
52        result
53    }
54
55    /// Async send (waits for capacity).  Notifies the handler on success.
56    pub async fn send(
57        &self,
58        msg: TargetMessage,
59    ) -> Result<(), mpsc::error::SendError<TargetMessage>> {
60        let result = self.inner.send(msg).await;
61        if result.is_ok() {
62            self.notify();
63        }
64        result
65    }
66}