zelos_trace_grpc/subscribe/
client.rs1use anyhow::Result;
2use tokio::sync::mpsc::Sender;
3use tokio_stream::wrappers::ReceiverStream;
4use tokio_util::sync::CancellationToken;
5use tonic::Streaming;
6use zelos_proto::trace::{
7 subscribe_request, trace_subscribe_client, SubscribeCommand, SubscribeRequest,
8 SubscribeResponse, UnsubscribeCommand,
9};
10
11pub struct TraceSubscribeClient {
12 req_sender: Sender<SubscribeRequest>,
14}
15
16impl TraceSubscribeClient {
17 pub async fn new(
19 sender: zelos_trace_types::ipc::Sender,
20 cancellation_token: CancellationToken,
21 address: String,
22 ) -> Result<(Self, impl Future<Output = Result<()>>)> {
23 let channel = zelos_proto::channel::create_channel(address)?;
25 let mut client = trace_subscribe_client::TraceSubscribeClient::new(channel)
26 .max_decoding_message_size(zelos_proto::MAX_GRPC_MESSAGE_SIZE)
27 .max_encoding_message_size(zelos_proto::MAX_GRPC_MESSAGE_SIZE);
28
29 let (req_sender, req_receiver) = tokio::sync::mpsc::channel(1);
31
32 let request_stream = tonic::Request::new(ReceiverStream::new(req_receiver));
34 let resp = client.subscribe(request_stream).await?;
35
36 let future = Self::run(resp.into_inner(), sender.clone(), cancellation_token);
38
39 Ok((Self { req_sender }, future))
40 }
41
42 async fn run(
44 mut stream: Streaming<SubscribeResponse>,
45 sender: zelos_trace_types::ipc::Sender,
46 cancellation_token: CancellationToken,
47 ) -> Result<()> {
48 loop {
49 tokio::select! {
50 msg = stream.message() => {
51 match msg {
52 Ok(Some(response)) => {
53 let ipc = response.as_ipc()?;
55 for m in ipc {
56 sender.send_async(m).await?;
57 }
58 }
59 Ok(None) => {
60 return Ok(());
62 }
63 Err(e) => {
64 return Err(e.into());
66 }
67 }
68 }
69 _ = cancellation_token.cancelled() => return Ok(())
70 }
71 }
72 }
73
74 pub async fn subscribe(&self, filter: Option<String>, start_time: Option<i64>) -> Result<()> {
76 self.req_sender
77 .send(SubscribeRequest {
78 cmd: Some(subscribe_request::Cmd::Subscribe(SubscribeCommand {
79 filter,
80 start_time,
81 })),
82 })
83 .await?;
84
85 Ok(())
86 }
87
88 pub async fn unsubscribe(&self, filter: Option<String>) -> Result<()> {
90 self.req_sender
91 .send(SubscribeRequest {
92 cmd: Some(subscribe_request::Cmd::Unsubscribe(UnsubscribeCommand {
93 filter,
94 })),
95 })
96 .await?;
97
98 Ok(())
99 }
100
101 pub async fn subscribe_all(&self) -> Result<()> {
103 self.subscribe(None, None).await
104 }
105
106 pub async fn unsubscribe_all(&self) -> Result<()> {
108 self.unsubscribe(None).await
109 }
110}