Create a stream of real-time changelog events matching `filter`, optionally also including historical events occuring after `synced-tip`
(
filter: ChangelogFilter,
listeners: Listeners,
query: &Query,
)
| 592 | // Create a stream of real-time changelog events matching `filter`, optionally also including |
| 593 | // historical events occuring after `synced-tip` |
| 594 | fn make_sse_stream( |
| 595 | filter: ChangelogFilter, |
| 596 | listeners: Listeners, |
| 597 | query: &Query, |
| 598 | ) -> Result<impl Stream<Item = Result<Event, warp::Error>>, Error> { |
| 599 | debug!("subscribing sse client with {:?}", filter); |
| 600 | |
| 601 | let (tx, rx) = tmpsc::unbounded_channel(); |
| 602 | let rx = UnboundedReceiverStream::new(rx); |
| 603 | listeners.lock().unwrap().push(Listener { |
| 604 | tx, |
| 605 | filter: filter.clone(), |
| 606 | }); |
| 607 | |
| 608 | // fetch historical changelog since the requested start point (if requesed) |
| 609 | let changelog = match &filter.synced_tip { |
| 610 | Some(synced_tip) => query.get_changelog_after(synced_tip)?, |
| 611 | None => vec![], |
| 612 | } |
| 613 | .into_iter() |
| 614 | .filter(move |change| filter.matches(change)); |
| 615 | // TODO don't produce unwanted events to begin with instead of filtering them |
| 616 | |
| 617 | Ok(tokio_stream::iter(changelog) |
| 618 | .chain(rx) |
| 619 | .map(make_sse_msg) |
| 620 | .map(Ok)) |
| 621 | } |
| 622 | |
| 623 | fn make_sse_msg(change: IndexChange) -> Event { |
| 624 | match &change { |
no test coverage detected