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