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}