|
1 | | -use std::{ |
2 | | - collections::VecDeque, |
3 | | - fmt::{self, Formatter}, |
4 | | - pin::Pin, |
5 | | - task::{ready, Context, Poll}, |
6 | | -}; |
| 1 | +mod task_id_stream; |
| 2 | +mod task_stream; |
| 3 | + |
| 4 | +use task_id_stream::TaskIdStream; |
| 5 | +use task_stream::TaskStream; |
7 | 6 |
|
8 | 7 | use crate::{ |
9 | 8 | clients::{ClientConnExt, ClientError}, |
10 | 9 | entity::{task::ProvisionableTask, Aggregator}, |
11 | 10 | handler::Error, |
12 | 11 | }; |
13 | | -use futures_lite::{stream::Stream, Future, StreamExt}; |
| 12 | +use futures_lite::StreamExt; |
14 | 13 | use serde::{de::DeserializeOwned, Serialize}; |
15 | 14 | use trillium::{HeaderValue, KnownHeaderName, Method}; |
16 | 15 | use trillium_client::{Client, Conn}; |
@@ -148,137 +147,3 @@ impl AggregatorClient { |
148 | 147 | TaskStream::new(self) |
149 | 148 | } |
150 | 149 | } |
151 | | - |
152 | | -#[derive(Clone, Debug)] |
153 | | -struct Page { |
154 | | - task_ids: VecDeque<String>, |
155 | | - pagination_token: Option<String>, |
156 | | -} |
157 | | - |
158 | | -impl From<TaskIds> for Page { |
159 | | - fn from( |
160 | | - TaskIds { |
161 | | - task_ids, |
162 | | - pagination_token, |
163 | | - }: TaskIds, |
164 | | - ) -> Self { |
165 | | - Page { |
166 | | - task_ids: task_ids.into_iter().map(|t| t.to_string()).collect(), |
167 | | - pagination_token, |
168 | | - } |
169 | | - } |
170 | | -} |
171 | | - |
172 | | -pub struct TaskIdStream<'a> { |
173 | | - client: &'a AggregatorClient, |
174 | | - page: Option<Page>, |
175 | | - future: Option<Pin<Box<dyn Future<Output = Result<TaskIds, ClientError>> + Send + 'a>>>, |
176 | | -} |
177 | | - |
178 | | -impl<'a> TaskIdStream<'a> { |
179 | | - fn new(client: &'a AggregatorClient) -> Self { |
180 | | - Self { |
181 | | - client, |
182 | | - page: None, |
183 | | - future: None, |
184 | | - } |
185 | | - } |
186 | | -} |
187 | | - |
188 | | -impl<'a> fmt::Debug for TaskIdStream<'a> { |
189 | | - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
190 | | - f.debug_struct("TaskIdStream") |
191 | | - .field("client", &self.client) |
192 | | - .field("current_page", &self.page) |
193 | | - .field("current_future", &"..") |
194 | | - .finish() |
195 | | - } |
196 | | -} |
197 | | - |
198 | | -impl Stream for TaskIdStream<'_> { |
199 | | - type Item = Result<String, ClientError>; |
200 | | - |
201 | | - fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> { |
202 | | - let Self { |
203 | | - client, |
204 | | - ref mut page, |
205 | | - ref mut future, |
206 | | - } = *self; |
207 | | - |
208 | | - loop { |
209 | | - if let Some(page) = page { |
210 | | - if let Some(task_id) = page.task_ids.pop_front() { |
211 | | - return Poll::Ready(Some(Ok(task_id))); |
212 | | - } |
213 | | - |
214 | | - if page.pagination_token.is_none() { |
215 | | - return Poll::Ready(None); |
216 | | - } |
217 | | - } |
218 | | - |
219 | | - if let Some(fut) = future { |
220 | | - *page = Some(ready!(Pin::new(&mut *fut).poll(cx))?.into()); |
221 | | - *future = None; |
222 | | - } else { |
223 | | - let pagination_token = page.as_ref().and_then(|page| page.pagination_token.clone()); |
224 | | - |
225 | | - *future = Some(Box::pin(async move { |
226 | | - client.get_task_id_page(pagination_token.as_deref()).await |
227 | | - })); |
228 | | - }; |
229 | | - } |
230 | | - } |
231 | | -} |
232 | | - |
233 | | -pub struct TaskStream<'a> { |
234 | | - client: &'a AggregatorClient, |
235 | | - task_id_stream: TaskIdStream<'a>, |
236 | | - task_future: Option< |
237 | | - Pin<Box<dyn Future<Output = Option<Result<TaskResponse, ClientError>>> + Send + 'a>>, |
238 | | - >, |
239 | | -} |
240 | | - |
241 | | -impl<'a> fmt::Debug for TaskStream<'a> { |
242 | | - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { |
243 | | - f.debug_struct("TaskStream").field("future", &"..").finish() |
244 | | - } |
245 | | -} |
246 | | - |
247 | | -impl<'a> TaskStream<'a> { |
248 | | - fn new(client: &'a AggregatorClient) -> Self { |
249 | | - Self { |
250 | | - task_id_stream: client.task_id_stream(), |
251 | | - client, |
252 | | - task_future: None, |
253 | | - } |
254 | | - } |
255 | | -} |
256 | | - |
257 | | -impl Stream for TaskStream<'_> { |
258 | | - type Item = Result<TaskResponse, ClientError>; |
259 | | - |
260 | | - fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> { |
261 | | - let Self { |
262 | | - client, |
263 | | - ref mut task_id_stream, |
264 | | - ref mut task_future, |
265 | | - } = *self; |
266 | | - |
267 | | - loop { |
268 | | - if let Some(future) = task_future { |
269 | | - let res = ready!(Pin::new(&mut *future).poll(cx)); |
270 | | - *task_future = None; |
271 | | - return Poll::Ready(res); |
272 | | - } |
273 | | - |
274 | | - *task_future = match ready!(Pin::new(&mut *task_id_stream).poll_next(cx)) { |
275 | | - Some(Ok(task_id)) => Some(Box::pin(async move { |
276 | | - let task_id = task_id; |
277 | | - Some(client.get_task(&task_id).await) |
278 | | - })), |
279 | | - None => return Poll::Ready(None), |
280 | | - Some(Err(e)) => return Poll::Ready(Some(Err(e))), |
281 | | - }; |
282 | | - } |
283 | | - } |
284 | | -} |
0 commit comments