rustrade_data/subscriber/
shared_stream.rs1use crate::{
10 Identifier, MarketStream, SnapshotFetcher,
11 error::DataError,
12 exchange::Connector,
13 instrument::InstrumentData,
14 process_buffered_events,
15 subscriber::{Subscribed, Subscriber},
16 subscription::{Subscription, SubscriptionKind},
17 transformer::ExchangeTransformer,
18};
19use futures::Stream;
20use rustrade_integration::{
21 Transformer,
22 protocol::{
23 StreamParser,
24 websocket::{WebSocketSerdeParser, WsError, WsMessage},
25 },
26 stream::ExchangeStream,
27};
28use std::{
29 pin::Pin,
30 task::{Context, Poll},
31};
32use tokio::sync::mpsc;
33
34pub trait SharedTransport:
41 Stream<Item = Result<WsMessage, WsError>> + Unpin + Send + sealed::Sealed
42{
43 type Attached: Send;
46
47 fn take_attached(&mut self) -> Self::Attached;
50}
51
52pub(crate) mod sealed {
53 pub trait Sealed {}
55}
56
57pub trait AttachedTransformer<Attached> {
62 fn attached(&mut self, attached: Attached);
64}
65
66impl<T> AttachedTransformer<()> for T {
67 fn attached(&mut self, (): ()) {}
68}
69
70pub struct SharedStream<Transport, StreamTransformer>
81where
82 Transport: SharedTransport,
83 StreamTransformer: Transformer,
84 WebSocketSerdeParser: StreamParser<StreamTransformer::Input>,
85{
86 inner: ExchangeStream<WebSocketSerdeParser, Transport, StreamTransformer>,
87}
88
89impl<Transport, StreamTransformer> std::fmt::Debug for SharedStream<Transport, StreamTransformer>
92where
93 Transport: SharedTransport,
94 StreamTransformer: Transformer,
95 WebSocketSerdeParser: StreamParser<StreamTransformer::Input>,
96{
97 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
98 f.debug_struct("SharedStream")
99 .field("buffered", &self.inner.buffer.len())
100 .finish_non_exhaustive()
101 }
102}
103
104impl<Transport, StreamTransformer> Stream for SharedStream<Transport, StreamTransformer>
105where
106 Transport: SharedTransport,
107 StreamTransformer: Transformer,
108 WebSocketSerdeParser: StreamParser<StreamTransformer::Input>,
109 ExchangeStream<WebSocketSerdeParser, Transport, StreamTransformer>:
110 Stream<Item = Result<StreamTransformer::Output, StreamTransformer::Error>> + Unpin,
111{
112 type Item = Result<StreamTransformer::Output, StreamTransformer::Error>;
113
114 fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
115 Pin::new(&mut self.get_mut().inner).poll_next(cx)
118 }
119}
120
121impl<Exchange, Instrument, Kind, Transport, StreamTransformer>
122 MarketStream<Exchange, Instrument, Kind> for SharedStream<Transport, StreamTransformer>
123where
124 Exchange: Connector + Send + Sync,
125 Exchange::Subscriber: Subscriber<Transport = Transport>,
126 Transport: SharedTransport,
127 Instrument: InstrumentData,
128 Kind: SubscriptionKind + Send + Sync,
129 Kind::Event: Send + Sync,
130 StreamTransformer: ExchangeTransformer<Exchange, Instrument::Key, Kind>
131 + AttachedTransformer<Transport::Attached>
132 + Send,
133 WebSocketSerdeParser:
134 StreamParser<StreamTransformer::Input, Message = WsMessage, Error = WsError>,
135{
136 async fn init<SnapFetcher>(
144 subscriber: &Exchange::Subscriber,
145 subscriptions: &[Subscription<Exchange, Instrument, Kind>],
146 ) -> Result<Self, DataError>
147 where
148 SnapFetcher: SnapshotFetcher<Exchange, Kind>,
149 Subscription<Exchange, Instrument, Kind>:
150 Identifier<Exchange::Channel> + Identifier<Exchange::Market>,
151 {
152 let Subscribed {
153 transport: mut attachment,
154 map: instrument_map,
155 buffered_websocket_events,
156 } = subscriber.subscribe(subscriptions).await?;
157
158 let initial_snapshots = SnapFetcher::fetch_snapshots(subscriptions).await?;
161
162 let (ws_sink_tx, _unread) = mpsc::unbounded_channel();
163
164 let mut transformer =
165 StreamTransformer::init(instrument_map, &initial_snapshots, ws_sink_tx).await?;
166 transformer.attached(attachment.take_attached());
167
168 let mut processed = process_buffered_events::<WebSocketSerdeParser, _>(
172 &mut transformer,
173 buffered_websocket_events,
174 );
175 processed.extend(initial_snapshots.into_iter().map(Ok));
176
177 Ok(Self {
178 inner: ExchangeStream::new(attachment, transformer, processed),
179 })
180 }
181}