Skip to content

Commit 3d01b42

Browse files
committed
fix(core): Rollback stream_impl
1 parent 4171d99 commit 3d01b42

File tree

1 file changed

+53
-52
lines changed

1 file changed

+53
-52
lines changed

crates/core/src/stream/stream_impl.rs

Lines changed: 53 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,7 @@ use futures::{
1616
};
1717
use tokio::{sync::OnceCell, task::spawn_blocking, time::sleep};
1818

19-
use super::{
20-
config::{STREAM_THROTTLE_HISTORICAL, STREAM_THROTTLE_LIVE},
21-
StreamError,
22-
};
19+
use super::{config, StreamError};
2320
use crate::{server::DeliverPolicy, types::StreamResponse};
2421

2522
pub type BoxedStoreItem = Result<StreamResponse, StreamError>;
@@ -90,7 +87,7 @@ impl<R: Record> Stream<R> {
9087
pub async fn publish(
9188
&self,
9289
subject: &str,
93-
response: &Arc<StreamResponse>,
90+
response: &StreamResponse,
9491
) -> Result<(), StreamError> {
9592
let broker = self.broker.clone();
9693
let response = response.clone();
@@ -117,33 +114,41 @@ impl<R: Record> Stream<R> {
117114
api_key_role: &ApiKeyRole,
118115
) -> BoxStream<'static, Result<StreamResponse, StreamError>> {
119116
let broker = self.broker.clone();
120-
let subject_ref = subject.clone();
117+
let subject = subject.clone();
121118
let stream = self.clone();
122119
let role = api_key_role.clone();
123-
let has_historical =
124-
role.has_scopes(&[ApiKeyRoleScope::HistoricalData]).is_ok();
125-
let has_live = role.has_scopes(&[ApiKeyRoleScope::LiveData]).is_ok();
126-
let throttle_historical = *STREAM_THROTTLE_HISTORICAL as u64;
127-
let throttle_live = *STREAM_THROTTLE_LIVE as u64;
128120
let stream = async_stream::try_stream! {
129-
if has_historical {
130-
if let DeliverPolicy::FromBlock { block_height } = deliver_policy {
131-
let mut historical = stream.historical_streaming(subject_ref.to_owned(), Some(block_height), &role);
132-
while let Some(result) = historical.next().await {
133-
yield result?;
134-
sleep(Duration::from_millis(throttle_historical)).await;
121+
match role.has_scopes(&[ApiKeyRoleScope::HistoricalData]) {
122+
Ok(_) => {
123+
if let DeliverPolicy::FromBlock { block_height } = deliver_policy {
124+
let mut historical = stream.historical_streaming(subject.to_owned(), Some(block_height), &role);
125+
while let Some(result) = historical.next().await {
126+
yield result?;
127+
let throttle_time = *config::STREAM_THROTTLE_HISTORICAL;
128+
sleep(Duration::from_millis(throttle_time as u64)).await;
129+
}
135130
}
136131
}
132+
Err(e) => {
133+
tracing::error!("Error subscribing to stream: {}", e);
134+
Err(StreamError::from(e))?;
135+
}
137136
}
138137

139-
if has_live {
140-
let mut live = broker.subscribe(&subject_ref.parse()).await?;
141-
while let Some(msg) = live.next().await {
142-
let msg = msg?;
143-
let stream_response = spawn_blocking(move || StreamResponse::decode_json(&msg))
144-
.await?;
145-
yield stream_response?;
146-
sleep(Duration::from_millis(throttle_live)).await;
138+
match role.has_scopes(&[ApiKeyRoleScope::LiveData]) {
139+
Ok(_) => {
140+
let mut live = broker.subscribe(&subject.parse()).await?;
141+
while let Some(msg) = live.next().await {
142+
let msg = msg?;
143+
let stream_response = spawn_blocking(move || StreamResponse::decode_json(&msg)).await??;
144+
yield stream_response;
145+
let throttle_time = *config::STREAM_THROTTLE_LIVE;
146+
sleep(Duration::from_millis(throttle_time as u64)).await;
147+
}
148+
}
149+
Err(e) => {
150+
tracing::error!("Error subscribing to stream: {}", e);
151+
Err(StreamError::from(e))?;
147152
}
148153
}
149154
};
@@ -156,8 +161,8 @@ impl<R: Record> Stream<R> {
156161
from_block: Option<BlockHeight>,
157162
role: &ApiKeyRole,
158163
) -> BoxStream<'static, Result<StreamResponse, StreamError>> {
159-
let store = self.store();
160-
let db = store.db.clone();
164+
let store = self.store().clone();
165+
let db = self.store().db.clone();
161166
let role = role.clone();
162167
let opts = if cfg!(any(test, feature = "test-helpers")) {
163168
QueryOptions::default()
@@ -167,39 +172,35 @@ impl<R: Record> Stream<R> {
167172

168173
let stream = async_stream::try_stream! {
169174
let mut current_height = from_block.unwrap_or_default();
170-
let mut last_height = find_last_block_height(&db, opts.clone()).await?;
171-
if let Err(e) = role.validate_historical_limit(last_height, current_height) {
172-
tracing::error!("Historical limit validation failed: {}", e);
173-
Err(StreamError::from(e))?;
174-
}
175-
176175
let mut opts = opts.with_from_block(Some(current_height));
176+
let mut last_height = find_last_block_height(&db, opts.clone()).await?;
177177
while current_height <= last_height {
178178
let items = store.find_many_by_subject(&subject, opts.clone()).await?;
179-
if items.is_empty() {
179+
for item in items {
180+
let subject = item.subject_str();
181+
let subject_id = item.subject_id();
182+
let block_height = item.block_height();
183+
role.validate_historical_limit(last_height, block_height)?;
184+
let value = item.encoded_value().to_vec();
185+
let pointer = item.into();
186+
let response = StreamResponse::new(subject, subject_id, &value, pointer.to_owned(), None)?;
187+
yield response;
188+
current_height = pointer.block_height;
189+
}
190+
opts.increment_offset();
191+
// When we reach the last known height, we need to check if any new blocks
192+
// were produced while we were processing the previous ones
193+
if current_height == last_height {
180194
let new_last_height = find_last_block_height(&db, opts.clone()).await?;
181195
if new_last_height > last_height {
196+
// Reset current_height back to process the blocks we haven't seen yet
197+
current_height = last_height;
182198
last_height = new_last_height;
183-
continue;
199+
} else {
200+
tracing::debug!("No new blocks found, stopping historical streaming on block {}", current_height);
201+
break
184202
}
185-
tracing::debug!("No new blocks found, stopping historical streaming on block {}", current_height);
186-
break;
187-
}
188-
189-
for item in items {
190-
let block_height = item.block_height();
191-
let record_pointer = item.to_owned().into();
192-
let response = StreamResponse::new(
193-
item.subject_str(),
194-
item.subject_id(),
195-
item.encoded_value(),
196-
record_pointer,
197-
None,
198-
)?;
199-
yield response;
200-
current_height = block_height;
201203
}
202-
opts = opts.with_from_block(Some(current_height));
203204
}
204205
};
205206
Box::pin(stream)

0 commit comments

Comments
 (0)