|
1 |
| -use async_std::sync; |
2 |
| -use std::io; |
3 |
| -use std::time::Duration; |
4 |
| - |
5 | 1 | use async_std::io::Read as AsyncRead;
|
6 | 2 | use async_std::prelude::*;
|
7 | 3 | use async_std::task::{ready, Context, Poll};
|
| 4 | + |
| 5 | +use std::io; |
8 | 6 | use std::pin::Pin;
|
9 |
| -use std::sync::atomic::{AtomicBool, Ordering}; |
10 |
| -use std::sync::Arc; |
11 |
| - |
12 |
| -use pin_project::{pin_project, pinned_drop}; |
13 |
| - |
14 |
| -#[pin_project(PinnedDrop)] |
15 |
| -/// An SSE protocol encoder. |
16 |
| -#[derive(Debug)] |
17 |
| -pub struct Encoder { |
18 |
| - buf: Option<Vec<u8>>, |
19 |
| - #[pin] |
20 |
| - receiver: sync::Receiver<Vec<u8>>, |
21 |
| - cursor: usize, |
22 |
| - disconnected: Arc<AtomicBool>, |
23 |
| -} |
| 7 | +use std::time::Duration; |
24 | 8 |
|
25 |
| -#[pinned_drop] |
26 |
| -impl PinnedDrop for Encoder { |
27 |
| - fn drop(self: Pin<&mut Self>) { |
28 |
| - self.disconnected.store(true, Ordering::Relaxed); |
| 9 | +pin_project_lite::pin_project! { |
| 10 | + /// An SSE protocol encoder. |
| 11 | + #[derive(Debug)] |
| 12 | + pub struct Encoder { |
| 13 | + buf: Option<Vec<u8>>, |
| 14 | + #[pin] |
| 15 | + receiver: async_channel::Receiver<Vec<u8>>, |
| 16 | + cursor: usize, |
29 | 17 | }
|
30 | 18 | }
|
31 | 19 |
|
@@ -91,79 +79,56 @@ impl AsyncRead for Encoder {
|
91 | 79 |
|
92 | 80 | /// The sending side of the encoder.
|
93 | 81 | #[derive(Debug, Clone)]
|
94 |
| -pub struct Sender { |
95 |
| - sender: sync::Sender<Vec<u8>>, |
96 |
| - disconnected: Arc<std::sync::atomic::AtomicBool>, |
97 |
| -} |
| 82 | +pub struct Sender(async_channel::Sender<Vec<u8>>); |
98 | 83 |
|
99 | 84 | /// Create a new SSE encoder.
|
100 | 85 | pub fn encode() -> (Sender, Encoder) {
|
101 |
| - let (sender, receiver) = sync::channel(1); |
102 |
| - let disconnected = Arc::new(AtomicBool::new(false)); |
103 |
| - |
| 86 | + let (sender, receiver) = async_channel::bounded(1); |
104 | 87 | let encoder = Encoder {
|
105 | 88 | receiver,
|
106 | 89 | buf: None,
|
107 | 90 | cursor: 0,
|
108 |
| - disconnected: disconnected.clone(), |
109 | 91 | };
|
110 |
| - |
111 |
| - let sender = Sender { |
112 |
| - sender, |
113 |
| - disconnected, |
114 |
| - }; |
115 |
| - |
116 |
| - (sender, encoder) |
| 92 | + (Sender(sender), encoder) |
117 | 93 | }
|
118 | 94 |
|
119 |
| -/// An error that represents that the [Encoder] has been dropped. |
120 |
| -#[derive(Debug, Eq, PartialEq)] |
121 |
| -pub struct DisconnectedError; |
122 |
| -impl std::error::Error for DisconnectedError {} |
123 |
| -impl std::fmt::Display for DisconnectedError { |
124 |
| - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
125 |
| - write!(f, "Disconnected") |
| 95 | +impl Sender { |
| 96 | + async fn inner_send(&self, bytes: impl Into<Vec<u8>>) -> io::Result<()> { |
| 97 | + self.0 |
| 98 | + .send(bytes.into()) |
| 99 | + .await |
| 100 | + .map_err(|_| io::Error::new(io::ErrorKind::ConnectionAborted, "sse disconnected")) |
126 | 101 | }
|
127 |
| -} |
128 | 102 |
|
129 |
| -#[must_use] |
130 |
| -impl Sender { |
131 | 103 | /// Send a new message over SSE.
|
132 |
| - pub async fn send( |
133 |
| - &self, |
134 |
| - name: &str, |
135 |
| - data: &str, |
136 |
| - id: Option<&str>, |
137 |
| - ) -> Result<(), DisconnectedError> { |
138 |
| - if self.disconnected.load(Ordering::Relaxed) { |
139 |
| - return Err(DisconnectedError); |
140 |
| - } |
141 |
| - |
| 104 | + pub async fn send(&self, name: &str, data: &str, id: Option<&str>) -> io::Result<()> { |
142 | 105 | // Write the event name
|
143 | 106 | let msg = format!("event:{}\n", name);
|
144 |
| - self.sender.send(msg.into_bytes()).await; |
| 107 | + self.inner_send(msg).await?; |
145 | 108 |
|
146 | 109 | // Write the id
|
147 | 110 | if let Some(id) = id {
|
148 |
| - self.sender.send(format!("id:{}\n", id).into_bytes()).await; |
| 111 | + self.inner_send(format!("id:{}\n", id)).await?; |
149 | 112 | }
|
150 | 113 |
|
151 | 114 | // Write the data section, and end.
|
152 | 115 | let msg = format!("data:{}\n\n", data);
|
153 |
| - self.sender.send(msg.into_bytes()).await; |
| 116 | + self.inner_send(msg).await?; |
| 117 | + |
154 | 118 | Ok(())
|
155 | 119 | }
|
156 | 120 |
|
157 | 121 | /// Send a new "retry" message over SSE.
|
158 |
| - pub async fn send_retry(&self, dur: Duration, id: Option<&str>) { |
| 122 | + pub async fn send_retry(&self, dur: Duration, id: Option<&str>) -> io::Result<()> { |
159 | 123 | // Write the id
|
160 | 124 | if let Some(id) = id {
|
161 |
| - self.sender.send(format!("id:{}\n", id).into_bytes()).await; |
| 125 | + self.inner_send(format!("id:{}\n", id)).await?; |
162 | 126 | }
|
163 | 127 |
|
164 | 128 | // Write the retry section, and end.
|
165 | 129 | let dur = dur.as_secs_f64() as u64;
|
166 | 130 | let msg = format!("retry:{}\n\n", dur);
|
167 |
| - self.sender.send(msg.into_bytes()).await; |
| 131 | + self.inner_send(msg).await?; |
| 132 | + Ok(()) |
168 | 133 | }
|
169 | 134 | }
|
0 commit comments