liminal_sdk/remote/websocket/
subscription_signals.rs1use super::subscription::{WebSocketDeliveredMessage, WebSocketSubscriptionStream};
6use crate::SdkError;
7use crate::remote::mailbox::{BlockingTake, ReaderEnd};
8use alloc::format;
9use alloc::sync::Arc;
10use std::net::Shutdown;
11
12impl WebSocketSubscriptionStream {
13 pub fn recv(&self) -> Result<WebSocketDeliveredMessage, SdkError> {
18 match self.mailbox.take_blocking(false)? {
19 BlockingTake::Item(message) => Ok(message),
20 BlockingTake::Ended(ReaderEnd::Failed(error) | ReaderEnd::PeerClosed(error)) => {
21 Err(error)
22 }
23 BlockingTake::Abandoned | BlockingTake::Ended(ReaderEnd::Stopped) => {
24 Err(SdkError::Connection {
25 description: "subscription receive failed: the subscription was closed".into(),
26 })
27 }
28 }
29 }
30
31 pub fn close_handle(
37 &self,
38 ) -> Result<impl Fn() -> Result<(), SdkError> + Send + Sync + use<>, SdkError> {
39 let socket = self
40 .shutdown
41 .try_clone()
42 .map_err(|error| SdkError::Connection {
43 description: format!("failed to clone subscription close signal: {error}"),
44 })?;
45 let mailbox = Arc::clone(&self.mailbox);
46 Ok(move || {
47 let abandoned = mailbox.abandon();
48 let shutdown = socket
49 .shutdown(Shutdown::Both)
50 .or_else(|error| {
51 if error.kind() == std::io::ErrorKind::NotConnected {
52 Ok(())
53 } else {
54 Err(error)
55 }
56 })
57 .map_err(|error| SdkError::Connection {
58 description: format!("failed to close subscription socket: {error}"),
59 });
60 abandoned.and(shutdown)
61 })
62 }
63}