Refactor one-before retrieve

This commit is contained in:
Dominik Werder
2024-08-16 10:53:32 +02:00
parent b52fbd9044
commit 9068b1bbad
25 changed files with 467 additions and 136 deletions
+4 -2
View File
@@ -11,8 +11,10 @@ Parameters:
- `channelName`: the name of the channel. - `channelName`: the name of the channel.
- `begDate`: start of the time range, inclusive. In ISO format e.g. `2024-02-15T12:41:00Z`. - `begDate`: start of the time range, inclusive. In ISO format e.g. `2024-02-15T12:41:00Z`.
- `endDate`: end of the time range, exclusive. - `endDate`: end of the time range, exclusive.
- `allowLargeResult=true` indicates that the client is prepared to accept also larger responses compared to - `oneBeforeRange`: if set to `true` the reponse will in addition also contain the most recent event before the given range.
what might be suitable for a typical browser. - `allowLargeResult=true` **DEPRECATED**. indicates that the client is prepared to accept also larger responses compared to
what might be suitable for a typical browser. Please download large result sets as
framed json or framed cbor streams, see below.
By default, events are returned as a json object. By default, events are returned as a json object.
+4 -4
View File
@@ -2,6 +2,7 @@ use crate::create_connection;
use crate::worker::PgQueue; use crate::worker::PgQueue;
use crate::ErrConv; use crate::ErrConv;
use err::Error; use err::Error;
use netpod::log::*;
use netpod::ChannelArchiver; use netpod::ChannelArchiver;
use netpod::ChannelSearchQuery; use netpod::ChannelSearchQuery;
use netpod::ChannelSearchResult; use netpod::ChannelSearchResult;
@@ -128,10 +129,9 @@ pub(super) async fn search_channel_scylla(
), ),
regop regop
); );
let rows = pgc let params: &[&(dyn tokio_postgres::types::ToSql + Sync)] = &[&ch_kind, &query.name_regex, &cb1, &cb2];
.query(sql, &[&ch_kind, &query.name_regex, &cb1, &cb2]) info!("search_channel_scylla {:?}", params);
.await let rows = pgc.query(sql, params).await.err_conv()?;
.err_conv()?;
let mut res = Vec::new(); let mut res = Vec::new();
for row in rows { for row in rows {
let series: i64 = row.get(0); let series: i64 = row.get(0);
+1 -2
View File
@@ -310,8 +310,7 @@ pub async fn connect_client(uri: &http::Uri) -> Result<SendRequest<StreamBody>,
} }
}); });
let stream = TcpStream::connect(format!("{host}:{port}")).await?; let stream = TcpStream::connect(format!("{host}:{port}")).await?;
#[cfg(DISABLED)] if false {
{
let executor = hyper_util::rt::TokioExecutor::new(); let executor = hyper_util::rt::TokioExecutor::new();
hyper::client::conn::http2::Builder::new(executor); hyper::client::conn::http2::Builder::new(executor);
} }
+1
View File
@@ -765,6 +765,7 @@ impl DataApiPython3DataStream {
let select = EventsSubQuerySelect::new( let select = EventsSubQuerySelect::new(
ChannelTypeConfigGen::SfDatabuffer(fetch_info.clone()), ChannelTypeConfigGen::SfDatabuffer(fetch_info.clone()),
self.range.clone().into(), self.range.clone().into(),
false,
TransformQuery::for_event_blobs(), TransformQuery::for_event_blobs(),
); );
let log_level = String::new(); let log_level = String::new();
+20 -17
View File
@@ -242,20 +242,21 @@ async fn proxy_http_service_inner(
} else if let Some(h) = super::api4::docs::DocsHandler::handler(&req) { } else if let Some(h) = super::api4::docs::DocsHandler::handler(&req) {
Ok(h.handle(req, ctx).await?) Ok(h.handle(req, ctx).await?)
} else { } else {
use std::fmt::Write; let headers: std::collections::BTreeMap<String, String> = req
let mut body = String::new(); .headers()
let out = &mut body; .iter()
write!(out, "<pre>\n")?; .map(|(k, v)| (k.to_string(), v.to_str().map_or(String::new(), |x| x.to_string())))
write!(out, "METHOD {:?}<br>\n", req.method())?; .collect();
write!(out, "URI {:?}<br>\n", req.uri())?; let res = serde_json::json!({
write!(out, "HOST {:?}<br>\n", req.uri().host())?; "method": req.method().to_string(),
write!(out, "PORT {:?}<br>\n", req.uri().port())?; "uri": req.uri().to_string(),
write!(out, "PATH {:?}<br>\n", req.uri().path())?; "host": req.uri().host().unwrap_or(""),
write!(out, "QUERY {:?}<br>\n", req.uri().query())?; "port": req.uri().port().map_or(String::new(), |x| x.to_string()),
for (hn, hv) in req.headers() { "path": req.uri().path(),
write!(out, "HEADER {hn:?}: {hv:?}<br>\n")?; "query": req.uri().query(),
} "headers": headers,
write!(out, "</pre>\n")?; });
let body = serde_json::to_string(&res).unwrap_or("{}".into());
Ok(response(StatusCode::NOT_FOUND).body(body_string(body))?) Ok(response(StatusCode::NOT_FOUND).body(body_string(body))?)
} }
} }
@@ -513,18 +514,20 @@ where
return Ok(response_err_msg(StatusCode::BAD_REQUEST, msg)?); return Ok(response_err_msg(StatusCode::BAD_REQUEST, msg)?);
} }
}; };
debug!("proxy_backend_query {:?} {:?}", query, req.uri()); trace!("proxy_backend_query {:?} {:?}", query, req.uri());
let timeout = query.timeout(); let timeout = query.timeout();
let timeout_next = timeout.saturating_sub(Duration::from_millis(1000)); let timeout_next = timeout.saturating_sub(Duration::from_millis(1000));
debug!("timeout {timeout:?} timeout_next {timeout_next:?}"); trace!("timeout {timeout:?} timeout_next {timeout_next:?}");
query.set_timeout(timeout_next); query.set_timeout(timeout_next);
let query = query; let query = query;
let backend = query.backend(); let backend = query.backend();
let uri_path = proxy_backend_query_helper_uri_path(req.uri().path(), &url); let uri_path = proxy_backend_query_helper_uri_path(req.uri().path(), &url);
debug!("uri_path {uri_path}"); trace!("uri_path {uri_path}");
let query_host = get_query_host_for_backend(backend, proxy_config)?; let query_host = get_query_host_for_backend(backend, proxy_config)?;
let mut url = Url::parse(&format!("{}{}", query_host, uri_path))?; let mut url = Url::parse(&format!("{}{}", query_host, uri_path))?;
trace!("query_host {query_host} uri_path {uri_path} query {query:?}");
query.append_to_url(&mut url); query.append_to_url(&mut url);
trace!("url {:?}", url);
proxy_backend_query_inner(req.headers(), url, timeout, ctx, proxy_config).await proxy_backend_query_inner(req.headers(), url, timeout, ctx, proxy_config).await
} }
+1 -1
View File
@@ -68,7 +68,7 @@ impl EventsHandler {
let url = req_uri_to_url(&head.uri)?; let url = req_uri_to_url(&head.uri)?;
let pairs = get_url_query_pairs(&url); let pairs = get_url_query_pairs(&url);
let evq = PlainEventsQuery::from_pairs(&pairs)?; let evq = PlainEventsQuery::from_pairs(&pairs)?;
debug!("{evq:?}"); debug!("{:?}", evq);
let query_host = get_query_host_for_backend(evq.backend(), proxy_config)?; let query_host = get_query_host_for_backend(evq.backend(), proxy_config)?;
let url_str = format!( let url_str = format!(
"{}{}", "{}{}",
+1 -3
View File
@@ -11,9 +11,7 @@ pub struct IsoDateTime(DateTime<Utc>);
impl IsoDateTime { impl IsoDateTime {
pub fn from_unix_millis(ms: u64) -> Self { pub fn from_unix_millis(ms: u64) -> Self {
let datetime = chrono::NaiveDateTime::from_timestamp_millis(ms as i64) let datetime = chrono::DateTime::from_timestamp_millis(ms as i64).unwrap();
.unwrap()
.and_utc();
Self(datetime) Self(datetime)
} }
} }
-1
View File
@@ -1,4 +1,3 @@
use netpod::log::*;
use netpod::range::evrange::SeriesRange; use netpod::range::evrange::SeriesRange;
// TODO rename, no more deque involved // TODO rename, no more deque involved
+3
View File
@@ -161,6 +161,7 @@ impl WithLen for Box<dyn TimeBinnable> {
} }
} }
#[allow(unused)]
impl RangeOverlapInfo for Box<dyn TimeBinnable> { impl RangeOverlapInfo for Box<dyn TimeBinnable> {
fn ends_before(&self, range: &SeriesRange) -> bool { fn ends_before(&self, range: &SeriesRange) -> bool {
todo!() todo!()
@@ -190,6 +191,7 @@ impl TimeBinnable for Box<dyn TimeBinnable> {
} }
} }
#[allow(unused)]
impl RangeOverlapInfo for Box<dyn Events> { impl RangeOverlapInfo for Box<dyn Events> {
fn ends_before(&self, range: &SeriesRange) -> bool { fn ends_before(&self, range: &SeriesRange) -> bool {
todo!() todo!()
@@ -455,6 +457,7 @@ impl TimeBinnerTy for TimeBinnerDynStruct2 {
} }
} }
#[allow(unused)]
impl TimeBinner for TimeBinnerDynStruct2 { impl TimeBinner for TimeBinnerDynStruct2 {
fn ingest(&mut self, item: &mut dyn TimeBinnable) { fn ingest(&mut self, item: &mut dyn TimeBinnable) {
todo!() todo!()
+1 -1
View File
@@ -17,7 +17,7 @@ macro_rules! trace_ingest {
($($arg:tt)*) => { trace!($($arg)*) }; ($($arg:tt)*) => { trace!($($arg)*) };
} }
#[cfg(DISABLED)] #[cfg(target_abi = "x32")]
impl<T> TimeBinner for T impl<T> TimeBinner for T
where where
T: TimeBinnerIngest, T: TimeBinnerIngest,
+17 -6
View File
@@ -74,6 +74,15 @@ macro_rules! trace2 {
($($arg:tt)*) => { trace!($($arg)*); }; ($($arg:tt)*) => { trace!($($arg)*); };
} }
#[allow(unused)]
macro_rules! trace_binning {
($($arg:tt)*) => {
if false {
trace!($($arg)*);
}
};
}
#[derive(Clone, PartialEq, Serialize, Deserialize)] #[derive(Clone, PartialEq, Serialize, Deserialize)]
pub struct EventsDim0NoPulse<STY> { pub struct EventsDim0NoPulse<STY> {
pub tss: VecDeque<u64>, pub tss: VecDeque<u64>,
@@ -667,7 +676,7 @@ impl<STY: ScalarOps> EventsDim0Aggregator<STY> {
fn reset_values(&mut self, range: SeriesRange) { fn reset_values(&mut self, range: SeriesRange) {
self.int_ts = range.beg_u64(); self.int_ts = range.beg_u64();
trace!("ON RESET SET int_ts {:10}", self.int_ts); trace_binning!("ON RESET SET int_ts {:10}", self.int_ts);
self.range = range; self.range = range;
self.count = 0; self.count = 0;
self.sum = 0.; self.sum = 0.;
@@ -707,9 +716,11 @@ impl<STY: ScalarOps> EventsDim0Aggregator<STY> {
fn result_reset_time_weight(&mut self, range: SeriesRange) -> BinsDim0<STY> { fn result_reset_time_weight(&mut self, range: SeriesRange) -> BinsDim0<STY> {
// TODO check callsite for correct expand status. // TODO check callsite for correct expand status.
debug!( trace_binning!(
"result_reset_time_weight calls apply_event_time_weight range {:?} items_seen {} count {}", "result_reset_time_weight calls apply_event_time_weight range {:?} items_seen {} count {}",
self.range, self.items_seen, self.count self.range,
self.items_seen,
self.count
); );
let range_beg = self.range.beg_u64(); let range_beg = self.range.beg_u64();
let range_end = self.range.end_u64(); let range_end = self.range.end_u64();
@@ -777,7 +788,7 @@ impl<STY: ScalarOps> TimeBinnableTypeAggregator for EventsDim0Aggregator<STY> {
} }
fn result_reset(&mut self, range: SeriesRange) -> Self::Output { fn result_reset(&mut self, range: SeriesRange) -> Self::Output {
trace!("result_reset {:?}", range); trace_binning!("result_reset {:?}", range);
if self.do_time_weight { if self.do_time_weight {
self.result_reset_time_weight(range) self.result_reset_time_weight(range)
} else { } else {
@@ -1066,10 +1077,10 @@ impl<STY: ScalarOps> EventsDim0TimeBinner<STY> {
fn next_bin_range(&mut self) -> Option<SeriesRange> { fn next_bin_range(&mut self) -> Option<SeriesRange> {
self.rix += 1; self.rix += 1;
if let Some(rng) = self.binrange.range_at(self.rix) { if let Some(rng) = self.binrange.range_at(self.rix) {
trace!("{} next_bin_range {:?}", Self::type_name(), rng); trace_binning!("{} next_bin_range {:?}", Self::type_name(), rng);
Some(rng) Some(rng)
} else { } else {
trace!("{} next_bin_range None", Self::type_name()); trace_binning!("{} next_bin_range None", Self::type_name());
None None
} }
} }
+6 -3
View File
@@ -22,7 +22,7 @@ macro_rules! trace_ingest {
#[allow(unused)] #[allow(unused)]
macro_rules! trace_ingest_item { macro_rules! trace_ingest_item {
($($arg:tt)*) => { ($($arg:tt)*) => {
if true { if false {
info!($($arg)*); info!($($arg)*);
} }
}; };
@@ -30,8 +30,11 @@ macro_rules! trace_ingest_item {
#[allow(unused)] #[allow(unused)]
macro_rules! trace2 { macro_rules! trace2 {
($($arg:tt)*) => {}; ($($arg:tt)*) => {
($($arg:tt)*) => { trace!($($arg)*); }; if false {
trace!($($arg)*);
}
};
} }
pub trait TimeBinnerCommonV0Trait { pub trait TimeBinnerCommonV0Trait {
+7
View File
@@ -3,6 +3,7 @@ pub mod histo;
pub mod query; pub mod query;
pub mod range; pub mod range;
pub mod status; pub mod status;
pub mod stream_impl_tracer;
pub mod streamext; pub mod streamext;
pub mod ttl; pub mod ttl;
@@ -116,6 +117,12 @@ pub const DATETIME_FMT_9MS: &str = "%Y-%m-%dT%H:%M:%S.%9fZ";
const TEST_BACKEND: &str = "testbackend-00"; const TEST_BACKEND: &str = "testbackend-00";
#[allow(non_upper_case_globals)]
pub const trigger: [&'static str; 1] = [
//
"S30CB05-VMCP-A010:PRESSURE",
];
pub struct OnDrop<F> pub struct OnDrop<F>
where where
F: FnOnce() -> (), F: FnOnce() -> (),
+43
View File
@@ -0,0 +1,43 @@
use crate::log::*;
pub struct StreamImplTracer {
name: String,
npoll_cnt: usize,
npoll_max: usize,
loop_cnt: usize,
loop_max: usize,
}
impl StreamImplTracer {
pub fn new(name: String, npoll_max: usize, loop_max: usize) -> Self {
Self {
name,
npoll_cnt: 0,
npoll_max,
loop_cnt: 0,
loop_max,
}
}
pub fn poll_enter(&mut self) -> bool {
self.npoll_cnt += 1;
if self.npoll_cnt >= self.npoll_max {
trace!("{} poll {} reached limit", self.name, self.npoll_cnt);
true
} else {
trace!("{} poll {}", self.name, self.npoll_cnt);
false
}
}
pub fn loop_enter(&mut self) -> bool {
self.loop_cnt += 1;
if self.loop_cnt >= self.loop_max {
trace!("{} loop {} reached limit", self.name, self.loop_cnt);
true
} else {
trace!("{} loop {}", self.name, self.loop_cnt);
false
}
}
}
+2 -1
View File
@@ -82,7 +82,8 @@ fn raw_data_00() {
ScalarType::I32, ScalarType::I32,
Shape::Scalar, Shape::Scalar,
); );
let select = EventsSubQuerySelect::new(fetch_info.into(), range.into(), TransformQuery::default_events()); let select =
EventsSubQuerySelect::new(fetch_info.into(), range.into(), false, TransformQuery::default_events());
let settings = EventsSubQuerySettings::default(); let settings = EventsSubQuerySettings::default();
let log_level = String::new(); let log_level = String::new();
let qu = EventsSubQuery::from_parts(select, settings, "dummy".into(), log_level); let qu = EventsSubQuery::from_parts(select, settings, "dummy".into(), log_level);
+6 -7
View File
@@ -31,13 +31,12 @@ pub async fn scylla_channel_event_stream(
debug!("scylla_channel_event_stream {evq:?}"); debug!("scylla_channel_event_stream {evq:?}");
// TODO depends in general on the query // TODO depends in general on the query
// TODO why both in PlainEventsQuery and as separate parameter? Check other usages. // TODO why both in PlainEventsQuery and as separate parameter? Check other usages.
// let do_one_before_range = evq.need_one_before_range(); let _series = SeriesId::new(chconf.series());
let do_one_before_range = false; let readopts = EventReadOpts::new(
let series = SeriesId::new(chconf.series()); evq.need_one_before_range(),
let scalar_type = chconf.scalar_type(); evq.need_value_data(),
let shape = chconf.shape(); evq.transform().enum_as_string().unwrap_or(false),
let do_test_stream_error = false; );
let readopts = EventReadOpts::new(evq.need_value_data(), evq.transform().enum_as_string().unwrap_or(false));
let stream: Pin<Box<dyn Stream<Item = _> + Send>> = if let Some(rt) = evq.use_rt() { let stream: Pin<Box<dyn Stream<Item = _> + Send>> = if let Some(rt) = evq.use_rt() {
let x = scyllaconn::events2::events::EventsStreamRt::new( let x = scyllaconn::events2::events::EventsStreamRt::new(
rt, rt,
+20 -8
View File
@@ -59,6 +59,7 @@ pub struct PlainEventsQuery {
log_level: String, log_level: String,
#[serde(default)] #[serde(default)]
use_rt: Option<RetentionTime>, use_rt: Option<RetentionTime>,
querymarker: String,
} }
impl PlainEventsQuery { impl PlainEventsQuery {
@@ -85,6 +86,7 @@ impl PlainEventsQuery {
create_errors: Vec::new(), create_errors: Vec::new(),
log_level: String::new(), log_level: String::new(),
use_rt: None, use_rt: None,
querymarker: String::new(),
} }
} }
@@ -97,7 +99,7 @@ impl PlainEventsQuery {
} }
pub fn one_before_range(&self) -> bool { pub fn one_before_range(&self) -> bool {
self.transform.need_one_before_range() self.one_before_range || self.transform.need_one_before_range()
} }
pub fn transform(&self) -> &TransformQuery { pub fn transform(&self) -> &TransformQuery {
@@ -296,6 +298,7 @@ impl FromUrl for PlainEventsQuery {
.map(Some) .map(Some)
.map_err(|_| Error::with_public_msg_no_trace(format!("can not parse useRt: {}", k))) .map_err(|_| Error::with_public_msg_no_trace(format!("can not parse useRt: {}", k)))
})?, })?,
querymarker: pairs.get("querymarker").map_or(String::new(), |x| x.to_string()),
}; };
Ok(ret) Ok(ret)
} }
@@ -308,12 +311,10 @@ impl AppendToUrl for PlainEventsQuery {
SeriesRange::PulseRange(_) => todo!(), SeriesRange::PulseRange(_) => todo!(),
} }
self.channel.append_to_url(url); self.channel.append_to_url(url);
{ let mut g = url.query_pairs_mut();
let mut g = url.query_pairs_mut(); g.append_pair("oneBeforeRange", &self.one_before_range().to_string());
if self.one_before_range() { g.append_pair("querymarker", &self.querymarker);
g.append_pair("oneBeforeRange", "true"); drop(g);
}
}
self.transform.append_to_url(url); self.transform.append_to_url(url);
let mut g = url.query_pairs_mut(); let mut g = url.query_pairs_mut();
if let Some(x) = &self.timeout { if let Some(x) = &self.timeout {
@@ -365,15 +366,22 @@ impl AppendToUrl for PlainEventsQuery {
pub struct EventsSubQuerySelect { pub struct EventsSubQuerySelect {
ch_conf: ChannelTypeConfigGen, ch_conf: ChannelTypeConfigGen,
range: SeriesRange, range: SeriesRange,
one_before_range: bool,
transform: TransformQuery, transform: TransformQuery,
wasm1: Option<String>, wasm1: Option<String>,
} }
impl EventsSubQuerySelect { impl EventsSubQuerySelect {
pub fn new(ch_info: ChannelTypeConfigGen, range: SeriesRange, transform: TransformQuery) -> Self { pub fn new(
ch_info: ChannelTypeConfigGen,
range: SeriesRange,
one_before_range: bool,
transform: TransformQuery,
) -> Self {
Self { Self {
ch_conf: ch_info, ch_conf: ch_info,
range, range,
one_before_range,
transform, transform,
wasm1: None, wasm1: None,
} }
@@ -510,6 +518,10 @@ impl EventsSubQuery {
&self.select.range &self.select.range
} }
pub fn need_one_before_range(&self) -> bool {
self.select.one_before_range
}
pub fn transform(&self) -> &TransformQuery { pub fn transform(&self) -> &TransformQuery {
&self.select.transform &self.select.transform
} }
+171 -38
View File
@@ -24,6 +24,15 @@ use std::pin::Pin;
use std::task::Context; use std::task::Context;
use std::task::Poll; use std::task::Poll;
#[allow(unused)]
macro_rules! trace_fetch {
($($arg:tt)*) => {
if true {
trace!($($arg)*);
}
};
}
#[allow(unused)] #[allow(unused)]
macro_rules! trace_emit { macro_rules! trace_emit {
($($arg:tt)*) => { ($($arg:tt)*) => {
@@ -46,11 +55,13 @@ macro_rules! warn_item {
pub struct EventReadOpts { pub struct EventReadOpts {
pub with_values: bool, pub with_values: bool,
pub enum_as_strings: bool, pub enum_as_strings: bool,
pub one_before: bool,
} }
impl EventReadOpts { impl EventReadOpts {
pub fn new(with_values: bool, enum_as_strings: bool) -> Self { pub fn new(one_before: bool, with_values: bool, enum_as_strings: bool) -> Self {
Self { Self {
one_before,
with_values, with_values,
enum_as_strings, enum_as_strings,
} }
@@ -84,14 +95,20 @@ enum ReadingState {
FetchEvents(FetchEvents), FetchEvents(FetchEvents),
} }
struct Reading { struct ReadingBck {
scyqueue: ScyllaQueue,
reading_state: ReadingState,
}
struct ReadingFwd {
scyqueue: ScyllaQueue, scyqueue: ScyllaQueue,
reading_state: ReadingState, reading_state: ReadingState,
} }
enum State { enum State {
Begin, Begin,
Reading(Reading), ReadingBck(ReadingBck),
ReadingFwd(ReadingFwd),
InputDone, InputDone,
Done, Done,
} }
@@ -105,6 +122,8 @@ pub struct EventsStreamRt {
state: State, state: State,
scyqueue: ScyllaQueue, scyqueue: ScyllaQueue,
msp_inp: MspStreamRt, msp_inp: MspStreamRt,
msp_buf: VecDeque<TsMs>,
msp_buf_bck: VecDeque<TsMs>,
out: VecDeque<Box<dyn Events>>, out: VecDeque<Box<dyn Events>>,
ts_seen_max: u64, ts_seen_max: u64,
} }
@@ -129,29 +148,43 @@ impl EventsStreamRt {
state: State::Begin, state: State::Begin,
scyqueue, scyqueue,
msp_inp, msp_inp,
msp_buf: VecDeque::new(),
msp_buf_bck: VecDeque::new(),
out: VecDeque::new(), out: VecDeque::new(),
ts_seen_max: 0, ts_seen_max: 0,
} }
} }
fn make_msp_read_fut(
msp_inp: &mut MspStreamRt,
) -> Pin<Box<dyn Future<Output = Option<Result<TsMs, crate::events2::msp::Error>>> + Send>> {
trace_fetch!("make_msp_read_fut");
let msp_inp = unsafe {
let ptr = msp_inp as *mut MspStreamRt;
&mut *ptr
};
let fut = Box::pin(msp_inp.next());
fut
}
fn make_read_events_fut( fn make_read_events_fut(
&mut self, &mut self,
ts_msp: TsMs, ts_msp: TsMs,
bck: bool,
scyqueue: ScyllaQueue, scyqueue: ScyllaQueue,
) -> Pin<Box<dyn Future<Output = Result<Box<dyn Events>, Error>> + Send>> { ) -> Pin<Box<dyn Future<Output = Result<Box<dyn Events>, Error>> + Send>> {
let fwd = true;
let opts = ReadNextValuesOpts::new( let opts = ReadNextValuesOpts::new(
self.rt.clone(), self.rt.clone(),
self.series.clone(), self.series.clone(),
ts_msp, ts_msp,
self.range.clone(), self.range.clone(),
fwd, !bck,
self.readopts.clone(), self.readopts.clone(),
scyqueue, scyqueue,
); );
let scalar_type = self.ch_conf.scalar_type().clone(); let scalar_type = self.ch_conf.scalar_type().clone();
let shape = self.ch_conf.shape().clone(); let shape = self.ch_conf.shape().clone();
debug!("make_read_events_fut {:?} {:?}", shape, scalar_type); trace_fetch!("make_read_events_fut bck {} {:?} {:?}", bck, shape, scalar_type);
let fut = async move { let fut = async move {
let ret = match &shape { let ret = match &shape {
Shape::Scalar => match &scalar_type { Shape::Scalar => match &scalar_type {
@@ -168,9 +201,10 @@ impl EventsStreamRt {
ScalarType::BOOL => read_next_values::<bool>(opts).await, ScalarType::BOOL => read_next_values::<bool>(opts).await,
ScalarType::STRING => read_next_values::<String>(opts).await, ScalarType::STRING => read_next_values::<String>(opts).await,
ScalarType::Enum => { ScalarType::Enum => {
debug!( trace_fetch!(
"make_read_events_fut {:?} {:?} ------------- good", "make_read_events_fut {:?} {:?} ------------- good",
shape, scalar_type shape,
scalar_type
); );
read_next_values::<EnumVariant>(opts).await read_next_values::<EnumVariant>(opts).await
} }
@@ -205,6 +239,60 @@ impl EventsStreamRt {
}; };
Box::pin(fut) Box::pin(fut)
} }
fn transition_to_bck_read(&mut self) {
trace_fetch!("transition_to_bck_read");
for ts in self.msp_buf.iter() {
if ts.ns() < self.range.beg() {
self.msp_buf_bck.push_front(ts.clone());
}
}
let c = self.msp_buf.iter().take_while(|x| x.ns() < self.range.beg()).count();
let g = c.max(1) - 1;
for _ in 0..g {
self.msp_buf.pop_front();
}
self.setup_bck_read();
}
fn setup_bck_read(&mut self) {
trace_fetch!("setup_bck_read");
if let Some(ts) = self.msp_buf_bck.pop_front() {
let scyqueue = self.scyqueue.clone();
let fut = self.make_read_events_fut(ts, true, scyqueue);
self.state = State::ReadingBck(ReadingBck {
scyqueue: self.scyqueue.clone(),
reading_state: ReadingState::FetchEvents(FetchEvents { fut }),
});
} else {
self.transition_to_fwd_read();
}
}
fn transition_to_fwd_read(&mut self) {
trace_fetch!("transition_to_fwd_read");
self.msp_buf_bck = VecDeque::new();
self.setup_fwd_read();
}
fn setup_fwd_read(&mut self) {
if let Some(ts) = self.msp_buf.pop_front() {
trace_fetch!("setup_fwd_read {ts}");
let scyqueue = self.scyqueue.clone();
let fut = self.make_read_events_fut(ts, false, scyqueue);
self.state = State::ReadingFwd(ReadingFwd {
scyqueue: self.scyqueue.clone(),
reading_state: ReadingState::FetchEvents(FetchEvents { fut }),
});
} else {
trace_fetch!("setup_fwd_read no msp");
let fut = Self::make_msp_read_fut(&mut self.msp_inp);
self.state = State::ReadingFwd(ReadingFwd {
scyqueue: self.scyqueue.clone(),
reading_state: ReadingState::FetchMsp(FetchMsp { fut }),
});
}
}
} }
impl Stream for EventsStreamRt { impl Stream for EventsStreamRt {
@@ -220,7 +308,7 @@ impl Stream for EventsStreamRt {
break Ready(Some(Err(Error::BadBatch))); break Ready(Some(Err(Error::BadBatch)));
} }
if let Some(item_min) = item.ts_min() { if let Some(item_min) = item.ts_min() {
if item_min < self.range.beg().ns() { if !self.readopts.one_before && item_min < self.range.beg().ns() {
warn_item!( warn_item!(
"{}out of range error A {} {:?}", "{}out of range error A {} {:?}",
"\n\n--------------------------\n", "\n\n--------------------------\n",
@@ -284,29 +372,84 @@ impl Stream for EventsStreamRt {
} }
break match &mut self.state { break match &mut self.state {
State::Begin => { State::Begin => {
let msp_inp = unsafe { if self.readopts.one_before {
let ptr = (&mut self.msp_inp) as *mut MspStreamRt; trace_fetch!("State::Begin Bck");
&mut *ptr let fut = Self::make_msp_read_fut(&mut self.msp_inp);
}; self.state = State::ReadingBck(ReadingBck {
let fut = Box::pin(msp_inp.next()); scyqueue: self.scyqueue.clone(),
self.state = State::Reading(Reading { reading_state: ReadingState::FetchMsp(FetchMsp { fut }),
scyqueue: self.scyqueue.clone(), });
reading_state: ReadingState::FetchMsp(FetchMsp { fut }), } else {
}); trace_fetch!("State::Begin Fwd");
let fut = Self::make_msp_read_fut(&mut self.msp_inp);
self.state = State::ReadingFwd(ReadingFwd {
scyqueue: self.scyqueue.clone(),
reading_state: ReadingState::FetchMsp(FetchMsp { fut }),
});
}
continue; continue;
} }
State::Reading(st) => match &mut st.reading_state { State::ReadingBck(st) => match &mut st.reading_state {
ReadingState::FetchMsp(st2) => match st2.fut.poll_unpin(cx) { ReadingState::FetchMsp(st2) => match st2.fut.poll_unpin(cx) {
Ready(Some(Ok(ts))) => { Ready(Some(Ok(ts))) => {
let scyqueue = st.scyqueue.clone(); trace_fetch!("ReadingBck FetchMsp {:?}", ts);
let fut = self.make_read_events_fut(ts, scyqueue); self.msp_buf.push_back(ts);
if let State::Reading(st) = &mut self.state { if ts.ns() >= self.range.beg() {
st.reading_state = ReadingState::FetchEvents(FetchEvents { fut }); self.transition_to_bck_read();
continue;
} else { } else {
self.state = State::Done; let fut = Self::make_msp_read_fut(&mut self.msp_inp);
Ready(Some(Err(Error::Logic))) self.state = State::ReadingBck(ReadingBck {
scyqueue: self.scyqueue.clone(),
reading_state: ReadingState::FetchMsp(FetchMsp { fut }),
});
} }
continue;
}
Ready(Some(Err(e))) => Ready(Some(Err(e.into()))),
Ready(None) => {
self.transition_to_bck_read();
continue;
}
Pending => Pending,
},
ReadingState::FetchEvents(st2) => match st2.fut.poll_unpin(cx) {
Ready(Ok(mut x)) => {
use items_2::merger::Mergeable;
trace_fetch!("ReadingBck FetchEvents got len {:?}", x.len());
if let Some(ix) = Mergeable::find_highest_index_lt(&x, self.range.beg().ns()) {
trace_fetch!("ReadingBck FetchEvents find_highest_index_lt {:?}", ix);
let mut y = Mergeable::new_empty(&x);
match Mergeable::drain_into(&mut x, &mut y, (ix, 1 + ix)) {
Ok(()) => {
trace_fetch!("ReadingBck FetchEvents drained y len {:?}", y.len());
self.out.push_back(y);
self.transition_to_fwd_read();
continue;
}
Err(e) => {
self.state = State::Done;
Ready(Some(Err(e.into())))
}
}
} else {
trace_fetch!("ReadingBck FetchEvents find_highest_index_lt None");
self.setup_bck_read();
continue;
}
}
Ready(Err(e)) => {
self.state = State::Done;
Ready(Some(Err(e.into())))
}
Pending => Pending,
},
},
State::ReadingFwd(st) => match &mut st.reading_state {
ReadingState::FetchMsp(st2) => match st2.fut.poll_unpin(cx) {
Ready(Some(Ok(ts))) => {
self.msp_buf.push_back(ts);
self.setup_fwd_read();
continue;
} }
Ready(Some(Err(e))) => Ready(Some(Err(e.into()))), Ready(Some(Err(e))) => Ready(Some(Err(e.into()))),
Ready(None) => { Ready(None) => {
@@ -318,18 +461,8 @@ impl Stream for EventsStreamRt {
ReadingState::FetchEvents(st2) => match st2.fut.poll_unpin(cx) { ReadingState::FetchEvents(st2) => match st2.fut.poll_unpin(cx) {
Ready(Ok(x)) => { Ready(Ok(x)) => {
self.out.push_back(x); self.out.push_back(x);
let msp_inp = unsafe { self.setup_fwd_read();
let ptr = (&mut self.msp_inp) as *mut MspStreamRt; continue;
&mut *ptr
};
let fut = Box::pin(msp_inp.next());
if let State::Reading(st) = &mut self.state {
st.reading_state = ReadingState::FetchMsp(FetchMsp { fut });
continue;
} else {
self.state = State::Done;
Ready(Some(Err(Error::Logic)))
}
} }
Ready(Err(e)) => { Ready(Err(e)) => {
self.state = State::Done; self.state = State::Done;
+66 -7
View File
@@ -5,17 +5,54 @@ use futures_util::StreamExt;
use items_0::Events; use items_0::Events;
use items_2::merger::Mergeable; use items_2::merger::Mergeable;
use netpod::log::*; use netpod::log::*;
use netpod::stream_impl_tracer::StreamImplTracer;
use netpod::TsNano; use netpod::TsNano;
use std::pin::Pin; use std::pin::Pin;
use std::task::Context; use std::task::Context;
use std::task::Poll; use std::task::Poll;
#[allow(unused)]
macro_rules! trace_transition {
($($arg:tt)*) => {
if true {
trace!($($arg)*);
}
};
}
#[allow(unused)]
macro_rules! trace_emit {
($($arg:tt)*) => {
if true {
trace!($($arg)*);
}
};
}
macro_rules! tracer_poll_enter {
($self:expr) => {
if false && $self.tracer.poll_enter() {
return Ready(Some(Err(Error::LimitPoll)));
}
};
}
macro_rules! tracer_loop_enter {
($self:expr) => {
if false && $self.tracer.loop_enter() {
return Ready(Some(Err(Error::LimitLoop)));
}
};
}
#[derive(Debug, ThisError)] #[derive(Debug, ThisError)]
#[cstm(name = "EventsFirstBefore")] #[cstm(name = "EventsFirstBefore")]
pub enum Error { pub enum Error {
Unordered, Unordered,
Logic, Logic,
Input(Box<dyn std::error::Error + Send>), Input(Box<dyn std::error::Error + Send>),
LimitPoll,
LimitLoop,
} }
pub enum Output<T> { pub enum Output<T> {
@@ -38,6 +75,7 @@ where
inp: S, inp: S,
state: State, state: State,
buf: Option<T>, buf: Option<T>,
tracer: StreamImplTracer,
} }
impl<S, T> FirstBeforeAndInside<S, T> impl<S, T> FirstBeforeAndInside<S, T>
@@ -46,11 +84,13 @@ where
T: Events + Mergeable + Unpin, T: Events + Mergeable + Unpin,
{ {
pub fn new(inp: S, ts0: TsNano) -> Self { pub fn new(inp: S, ts0: TsNano) -> Self {
trace_transition!("FirstBeforeAndInside::new");
Self { Self {
ts0, ts0,
inp, inp,
state: State::Begin, state: State::Begin,
buf: None, buf: None,
tracer: StreamImplTracer::new("FirstBeforeAndInside".into(), 2000, 100),
} }
} }
} }
@@ -65,7 +105,9 @@ where
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> { fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
use Poll::*; use Poll::*;
tracer_poll_enter!(self);
loop { loop {
tracer_loop_enter!(self);
break match &self.state { break match &self.state {
State::Begin => match self.inp.poll_next_unpin(cx) { State::Begin => match self.inp.poll_next_unpin(cx) {
Ready(Some(Ok(mut item))) => { Ready(Some(Ok(mut item))) => {
@@ -79,8 +121,13 @@ where
// Separate events into before and bulk // Separate events into before and bulk
let tss = item.tss(); let tss = item.tss();
let pp = tss.partition_point(|&x| x < self.ts0.ns()); let pp = tss.partition_point(|&x| x < self.ts0.ns());
if pp >= tss.len() { trace_transition!("partition_point {pp:?} {n:?}", n = tss.len());
// all entries are before if pp > item.len() {
error!("bad partition point {} {}", pp, item.len());
self.state = State::Done;
Ready(Some(Err(Error::Logic)))
} else if pp == item.len() {
// all entries are before, or empty item
if self.buf.is_none() { if self.buf.is_none() {
self.buf = Some(item.new_empty()); self.buf = Some(item.new_empty());
} }
@@ -95,16 +142,19 @@ where
} }
} else if pp == 0 { } else if pp == 0 {
// all entries are bulk // all entries are bulk
debug!("transition immediately to bulk"); trace_transition!("transition immediately to bulk");
self.state = State::Bulk; self.state = State::Bulk;
let o1 = core::mem::replace(&mut self.buf, Some(item.new_empty())) let o1 = core::mem::replace(&mut self.buf, Some(item.new_empty()))
.unwrap_or_else(|| item.new_empty()); .unwrap_or_else(|| item.new_empty());
Ready(Some(Ok(Output::First(o1, item)))) Ready(Some(Ok(Output::First(o1, item))))
} else { } else {
// mixed // mixed
if self.buf.is_none() {
self.buf = Some(item.new_empty());
}
match item.drain_into_evs(self.buf.as_mut().unwrap(), (0, pp)) { match item.drain_into_evs(self.buf.as_mut().unwrap(), (0, pp)) {
Ok(()) => { Ok(()) => {
debug!("transition with mixed to bulk"); trace_transition!("transition with mixed to bulk");
self.state = State::Bulk; self.state = State::Bulk;
let o1 = core::mem::replace(&mut self.buf, Some(item.new_empty())) let o1 = core::mem::replace(&mut self.buf, Some(item.new_empty()))
.unwrap_or_else(|| item.new_empty()); .unwrap_or_else(|| item.new_empty());
@@ -124,12 +174,21 @@ where
} }
Ready(None) => { Ready(None) => {
self.state = State::Done; self.state = State::Done;
Ready(None) if let Some(x) = self.buf.take() {
let empty = x.new_empty();
Ready(Some(Ok(Output::First(x, empty))))
} else {
Ready(None)
}
} }
Pending => Pending, Pending => Pending,
}, },
State::Bulk => { State::Bulk => {
if self.buf.as_ref().map_or(0, |x| x.len()) != 0 { if self.buf.as_ref().map_or(0, |x| x.len()) != 0 {
error!(
"State::Bulk but buf non-empty {}",
self.buf.as_ref().map_or(0, |x| x.len())
);
self.state = State::Done; self.state = State::Done;
Ready(Some(Err(Error::Logic))) Ready(Some(Err(Error::Logic)))
} else { } else {
@@ -140,7 +199,7 @@ where
let e = Error::Unordered; let e = Error::Unordered;
Ready(Some(Err(e))) Ready(Some(Err(e)))
} else { } else {
debug!("output bulk item len {}", item.len()); trace_emit!("output bulk item len {}", item.len());
Ready(Some(Ok(Output::Bulk(item)))) Ready(Some(Ok(Output::Bulk(item))))
} }
} }
@@ -149,7 +208,7 @@ where
Ready(Some(Err(Error::Input(Box::new(e))))) Ready(Some(Err(Error::Input(Box::new(e)))))
} }
Ready(None) => { Ready(None) => {
debug!("in bulk, input done"); trace_emit!("in bulk, input done");
self.state = State::Done; self.state = State::Done;
Ready(None) Ready(None)
} }
+88 -30
View File
@@ -16,6 +16,7 @@ use items_2::merger::Mergeable;
use netpod::log::*; use netpod::log::*;
use netpod::range::evrange::NanoRange; use netpod::range::evrange::NanoRange;
use netpod::range::evrange::SeriesRange; use netpod::range::evrange::SeriesRange;
use netpod::stream_impl_tracer::StreamImplTracer;
use netpod::ttl::RetentionTime; use netpod::ttl::RetentionTime;
use netpod::ChConf; use netpod::ChConf;
use std::collections::VecDeque; use std::collections::VecDeque;
@@ -23,6 +24,40 @@ use std::pin::Pin;
use std::task::Context; use std::task::Context;
use std::task::Poll; use std::task::Poll;
#[allow(unused)]
macro_rules! trace_fetch {
($($arg:tt)*) => {
if true {
trace!($($arg)*);
}
};
}
#[allow(unused)]
macro_rules! trace_emit {
($($arg:tt)*) => {
if true {
trace!($($arg)*);
}
};
}
macro_rules! tracer_poll_enter {
($self:expr) => {
if false && $self.tracer.poll_enter() {
return Ready(Some(Err(Error::LimitPoll)));
}
};
}
macro_rules! tracer_loop_enter {
($self:expr) => {
if false && $self.tracer.loop_enter() {
return Ready(Some(Err(Error::LimitLoop)));
}
};
}
#[derive(Debug, ThisError)] #[derive(Debug, ThisError)]
#[cstm(name = "EventsMergeRt")] #[cstm(name = "EventsMergeRt")]
pub enum Error { pub enum Error {
@@ -31,6 +66,8 @@ pub enum Error {
Logic, Logic,
OrderMin, OrderMin,
OrderMax, OrderMax,
LimitPoll,
LimitLoop,
} }
#[allow(unused)] #[allow(unused)]
@@ -116,10 +153,12 @@ pub struct MergeRts {
out: VecDeque<ChannelEvents>, out: VecDeque<ChannelEvents>,
buf_before: Option<ChannelEvents>, buf_before: Option<ChannelEvents>,
ts_seen_max: u64, ts_seen_max: u64,
tracer: StreamImplTracer,
} }
impl MergeRts { impl MergeRts {
pub fn new(ch_conf: ChConf, range: ScyllaSeriesRange, readopts: EventReadOpts, scyqueue: ScyllaQueue) -> Self { pub fn new(ch_conf: ChConf, range: ScyllaSeriesRange, readopts: EventReadOpts, scyqueue: ScyllaQueue) -> Self {
info!("MergeRts readopts {readopts:?}");
Self { Self {
ch_conf, ch_conf,
range_mt: range.clone(), range_mt: range.clone(),
@@ -137,6 +176,7 @@ impl MergeRts {
out: VecDeque::new(), out: VecDeque::new(),
buf_before: None, buf_before: None,
ts_seen_max: 0, ts_seen_max: 0,
tracer: StreamImplTracer::new("MergeRts".into(), 2000, 2000),
} }
} }
@@ -145,7 +185,7 @@ impl MergeRts {
let limbuf = &VecDeque::new(); let limbuf = &VecDeque::new();
let inpdst = &mut self.inp_st; let inpdst = &mut self.inp_st;
let range = Self::constrained_range(&self.range, limbuf); let range = Self::constrained_range(&self.range, limbuf);
debug!("setup_first_st constrained beg {}", range.beg().ns()); trace_fetch!("setup_first_st constrained beg {}", range.beg().ns());
let tsbeg = range.beg(); let tsbeg = range.beg();
let inp = EventsStreamRt::new( let inp = EventsStreamRt::new(
rt, rt,
@@ -164,7 +204,7 @@ impl MergeRts {
let inpdst = &mut self.inp_mt; let inpdst = &mut self.inp_mt;
let range = Self::constrained_range(&self.range_mt, limbuf); let range = Self::constrained_range(&self.range_mt, limbuf);
self.range_lt = range.clone(); self.range_lt = range.clone();
debug!("setup_first_mt constrained beg {}", range.beg().ns()); trace_fetch!("setup_first_mt constrained beg {}", range.beg().ns());
let tsbeg = range.beg(); let tsbeg = range.beg();
let inp = EventsStreamRt::new( let inp = EventsStreamRt::new(
rt, rt,
@@ -182,7 +222,7 @@ impl MergeRts {
let limbuf = &self.buf_mt; let limbuf = &self.buf_mt;
let inpdst = &mut self.inp_lt; let inpdst = &mut self.inp_lt;
let range = Self::constrained_range(&self.range_lt, limbuf); let range = Self::constrained_range(&self.range_lt, limbuf);
debug!("setup_first_lt constrained beg {}", range.beg().ns()); trace_fetch!("setup_first_lt constrained beg {}", range.beg().ns());
let tsbeg = range.beg(); let tsbeg = range.beg();
let inp = EventsStreamRt::new( let inp = EventsStreamRt::new(
rt, rt,
@@ -196,37 +236,35 @@ impl MergeRts {
} }
fn setup_read_st(&mut self) -> ReadEvents { fn setup_read_st(&mut self) -> ReadEvents {
let stream = unsafe { &mut *(self.inp_st.as_mut().unwrap().as_mut() as *mut TI) }; trace_fetch!("setup_read_st");
let fut = Box::pin(stream.next()); Self::setup_read_any(&mut self.inp_st)
ReadEvents { fut }
} }
fn setup_read_mt(&mut self) -> ReadEvents { fn setup_read_mt(&mut self) -> ReadEvents {
let stream = unsafe { &mut *(self.inp_mt.as_mut().unwrap().as_mut() as *mut TI) }; trace_fetch!("setup_read_mt");
let fut = Box::pin(stream.next()); Self::setup_read_any(&mut self.inp_mt)
ReadEvents { fut }
} }
fn setup_read_lt(&mut self) -> ReadEvents { fn setup_read_lt(&mut self) -> ReadEvents {
let stream = unsafe { &mut *(self.inp_lt.as_mut().unwrap().as_mut() as *mut TI) }; trace_fetch!("setup_read_lt");
let fut = Box::pin(stream.next()); Self::setup_read_any(&mut self.inp_lt)
ReadEvents { fut }
} }
fn setup_read_any(inp: &mut Option<Box<TI>>) -> ReadEvents { fn setup_read_any(inp: &mut Option<Box<TI>>) -> ReadEvents {
trace_fetch!("setup_read_any");
let stream = unsafe { &mut *(inp.as_mut().unwrap().as_mut() as *mut TI) }; let stream = unsafe { &mut *(inp.as_mut().unwrap().as_mut() as *mut TI) };
let fut = Box::pin(stream.next()); let fut = Box::pin(stream.next());
ReadEvents { fut } ReadEvents { fut }
} }
fn constrained_range(full: &ScyllaSeriesRange, buf: &VecDeque<ChannelEvents>) -> ScyllaSeriesRange { fn constrained_range(full: &ScyllaSeriesRange, buf: &VecDeque<ChannelEvents>) -> ScyllaSeriesRange {
debug!("constrained_range {:?} {:?}", full, buf.front()); trace_fetch!("constrained_range {:?} {:?}", full, buf.front());
if let Some(e) = buf.front() { if let Some(e) = buf.front() {
if let Some(ts) = e.ts_min() { if let Some(ts) = e.ts_min() {
let nrange = NanoRange::from((full.beg().ns(), ts)); let nrange = NanoRange::from((full.beg().ns(), ts));
ScyllaSeriesRange::from(&SeriesRange::from(nrange)) ScyllaSeriesRange::from(&SeriesRange::from(nrange))
} else { } else {
debug!("no ts even though should not have empty buffers"); debug!("constrained_range no ts even though should not have empty buffers");
full.clone() full.clone()
} }
} else { } else {
@@ -235,6 +273,7 @@ impl MergeRts {
} }
fn handle_first_st(&mut self, mut before: ChannelEvents, bulk: ChannelEvents) { fn handle_first_st(&mut self, mut before: ChannelEvents, bulk: ChannelEvents) {
trace_fetch!("handle_first_st");
Self::move_latest_to_before_buf(&mut before, &mut self.buf_before); Self::move_latest_to_before_buf(&mut before, &mut self.buf_before);
self.buf_st.push_back(bulk); self.buf_st.push_back(bulk);
self.setup_first_mt(); self.setup_first_mt();
@@ -242,6 +281,7 @@ impl MergeRts {
} }
fn handle_first_mt(&mut self, mut before: ChannelEvents, bulk: ChannelEvents) { fn handle_first_mt(&mut self, mut before: ChannelEvents, bulk: ChannelEvents) {
trace_fetch!("handle_first_mt");
Self::move_latest_to_before_buf(&mut before, &mut self.buf_before); Self::move_latest_to_before_buf(&mut before, &mut self.buf_before);
self.buf_mt.push_back(bulk); self.buf_mt.push_back(bulk);
self.setup_first_lt(); self.setup_first_lt();
@@ -249,27 +289,39 @@ impl MergeRts {
} }
fn handle_first_lt(&mut self, mut before: ChannelEvents, bulk: ChannelEvents) { fn handle_first_lt(&mut self, mut before: ChannelEvents, bulk: ChannelEvents) {
trace_fetch!("handle_first_lt");
Self::move_latest_to_before_buf(&mut before, &mut self.buf_before); Self::move_latest_to_before_buf(&mut before, &mut self.buf_before);
self.buf_lt.push_back(bulk); self.buf_lt.push_back(bulk);
self.push_out_one_before();
let buf = core::mem::replace(&mut self.buf_lt, VecDeque::new()); let buf = core::mem::replace(&mut self.buf_lt, VecDeque::new());
self.state = State::ReadingLt(None, buf, self.inp_lt.take()); self.state = State::ReadingLt(None, buf, self.inp_lt.take());
} }
fn move_latest_to_before_buf(before: &mut ChannelEvents, buf: &mut Option<ChannelEvents>) { fn move_latest_to_before_buf(before: &mut ChannelEvents, buf: &mut Option<ChannelEvents>) {
trace_fetch!("move_latest_to_before_buf");
if buf.is_none() { if buf.is_none() {
*buf = Some(before.new_empty()); *buf = Some(before.new_empty());
} }
let buf = buf.as_mut().unwrap(); let buf = buf.as_mut().unwrap();
if let Some(tsn) = before.ts_max() { if let Some(tsn) = before.ts_max() {
if let Some(tse) = buf.ts_max() { if buf.ts_max().map_or(true, |x| tsn > x) {
if tsn > tse { let n = before.len();
let n = before.len(); buf.clear();
buf.clear(); before.drain_into(buf, (n - 1, n)).unwrap();
before.drain_into(buf, (n - 1, n)).unwrap();
}
} }
} }
} }
fn push_out_one_before(&mut self) {
if let Some(buf) = self.buf_before.take() {
trace_fetch!("push_out_one_before len {len:?}", len = buf.len());
if buf.len() != 0 {
self.out.push_back(buf);
}
} else {
trace_fetch!("push_out_one_before no buffer");
}
}
} }
impl Stream for MergeRts { impl Stream for MergeRts {
@@ -277,13 +329,15 @@ impl Stream for MergeRts {
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> { fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
use Poll::*; use Poll::*;
tracer_poll_enter!(self);
let mut out2 = VecDeque::new(); let mut out2 = VecDeque::new();
loop { loop {
tracer_loop_enter!(self);
while let Some(x) = out2.pop_front() { while let Some(x) = out2.pop_front() {
self.out.push_back(x); self.out.push_back(x);
} }
if let Some(item) = self.out.pop_front() { if let Some(item) = self.out.pop_front() {
debug!("emit item {} {:?}", items_0::Events::verify(&item), item); trace_emit!("emit item {} {:?}", items_0::Events::verify(&item), item);
if items_0::Events::verify(&item) != true { if items_0::Events::verify(&item) != true {
debug!("{}bad item {:?}", "\n\n--------------------------\n", item); debug!("{}bad item {:?}", "\n\n--------------------------\n", item);
self.state = State::Done; self.state = State::Done;
@@ -310,6 +364,9 @@ impl Stream for MergeRts {
self.ts_seen_max = item_max; self.ts_seen_max = item_max;
} }
} }
if let Some(ix) = item.find_highest_index_lt(self.range.beg().ns()) {
trace_fetch!("see item before range ix {ix}");
}
break Ready(Some(Ok(item))); break Ready(Some(Ok(item)));
} }
break match &mut self.state { break match &mut self.state {
@@ -321,7 +378,7 @@ impl Stream for MergeRts {
State::FetchFirstSt(st2) => match st2.fut.poll_unpin(cx) { State::FetchFirstSt(st2) => match st2.fut.poll_unpin(cx) {
Ready(Some(Ok(x))) => match x { Ready(Some(Ok(x))) => match x {
firstbefore::Output::First(before, bulk) => { firstbefore::Output::First(before, bulk) => {
debug!("have first from ST"); trace_fetch!("have first from ST");
self.handle_first_st(before, bulk); self.handle_first_st(before, bulk);
continue; continue;
} }
@@ -336,7 +393,7 @@ impl Stream for MergeRts {
Ready(Some(Err(e.into()))) Ready(Some(Err(e.into())))
} }
Ready(None) => { Ready(None) => {
debug!("no first from ST"); trace_fetch!("no first from ST");
self.inp_st = None; self.inp_st = None;
self.setup_first_mt(); self.setup_first_mt();
self.state = State::FetchFirstMt(self.setup_read_mt()); self.state = State::FetchFirstMt(self.setup_read_mt());
@@ -347,7 +404,7 @@ impl Stream for MergeRts {
State::FetchFirstMt(st2) => match st2.fut.poll_unpin(cx) { State::FetchFirstMt(st2) => match st2.fut.poll_unpin(cx) {
Ready(Some(Ok(x))) => match x { Ready(Some(Ok(x))) => match x {
firstbefore::Output::First(before, bulk) => { firstbefore::Output::First(before, bulk) => {
debug!("have first from MT"); trace_fetch!("have first from MT");
self.handle_first_mt(before, bulk); self.handle_first_mt(before, bulk);
continue; continue;
} }
@@ -362,7 +419,7 @@ impl Stream for MergeRts {
Ready(Some(Err(e.into()))) Ready(Some(Err(e.into())))
} }
Ready(None) => { Ready(None) => {
debug!("no first from MT"); trace_fetch!("no first from MT");
self.inp_mt = None; self.inp_mt = None;
self.setup_first_lt(); self.setup_first_lt();
self.state = State::FetchFirstLt(self.setup_read_lt()); self.state = State::FetchFirstLt(self.setup_read_lt());
@@ -373,7 +430,7 @@ impl Stream for MergeRts {
State::FetchFirstLt(st2) => match st2.fut.poll_unpin(cx) { State::FetchFirstLt(st2) => match st2.fut.poll_unpin(cx) {
Ready(Some(Ok(x))) => match x { Ready(Some(Ok(x))) => match x {
firstbefore::Output::First(before, bulk) => { firstbefore::Output::First(before, bulk) => {
debug!("have first from LT"); trace_fetch!("have first from LT");
self.handle_first_lt(before, bulk); self.handle_first_lt(before, bulk);
continue; continue;
} }
@@ -388,8 +445,9 @@ impl Stream for MergeRts {
Ready(Some(Err(e.into()))) Ready(Some(Err(e.into())))
} }
Ready(None) => { Ready(None) => {
debug!("no first from LT"); trace_fetch!("no first from LT");
self.inp_lt = None; self.inp_lt = None;
self.push_out_one_before();
let buf = core::mem::replace(&mut self.buf_lt, VecDeque::new()); let buf = core::mem::replace(&mut self.buf_lt, VecDeque::new());
self.state = State::ReadingLt(None, buf, self.inp_lt.take()); self.state = State::ReadingLt(None, buf, self.inp_lt.take());
continue; continue;
@@ -433,7 +491,7 @@ impl Stream for MergeRts {
self.state = State::ReadingLt(Some(Self::setup_read_any(inp)), buf, inp.take()); self.state = State::ReadingLt(Some(Self::setup_read_any(inp)), buf, inp.take());
continue; continue;
} else { } else {
debug!("transition ReadingLt to ReadingMt"); trace_emit!("transition ReadingLt to ReadingMt");
let buf = core::mem::replace(&mut self.buf_mt, VecDeque::new()); let buf = core::mem::replace(&mut self.buf_mt, VecDeque::new());
self.state = State::ReadingMt(None, buf, self.inp_mt.take()); self.state = State::ReadingMt(None, buf, self.inp_mt.take());
continue; continue;
@@ -476,7 +534,7 @@ impl Stream for MergeRts {
self.state = State::ReadingMt(Some(Self::setup_read_any(inp)), buf, inp.take()); self.state = State::ReadingMt(Some(Self::setup_read_any(inp)), buf, inp.take());
continue; continue;
} else { } else {
debug!("transition ReadingMt to ReadingSt"); trace_emit!("transition ReadingMt to ReadingSt");
let buf = core::mem::replace(&mut self.buf_st, VecDeque::new()); let buf = core::mem::replace(&mut self.buf_st, VecDeque::new());
self.state = State::ReadingSt(None, buf, self.inp_st.take()); self.state = State::ReadingSt(None, buf, self.inp_st.take());
continue; continue;
@@ -519,7 +577,7 @@ impl Stream for MergeRts {
self.state = State::ReadingSt(Some(Self::setup_read_any(inp)), buf, inp.take()); self.state = State::ReadingSt(Some(Self::setup_read_any(inp)), buf, inp.take());
continue; continue;
} else { } else {
debug!("fully done"); trace_emit!("fully done");
Ready(None) Ready(None)
} }
} }
-4
View File
@@ -159,7 +159,6 @@ impl ScyllaWorker {
let stmts = Arc::new(stmts); let stmts = Arc::new(stmts);
info!("scylla worker PREPARE DONE"); info!("scylla worker PREPARE DONE");
loop { loop {
info!("scylla worker WAIT FOR JOB");
let x = self.rx.recv().await; let x = self.rx.recv().await;
let job = match x { let job = match x {
Ok(x) => x, Ok(x) => x,
@@ -169,14 +168,12 @@ impl ScyllaWorker {
}; };
match job { match job {
Job::FindTsMsp(rt, series, range, bck, tx) => { Job::FindTsMsp(rt, series, range, bck, tx) => {
info!("scylla worker Job::FindTsMsp");
let res = crate::events2::msp::find_ts_msp(&rt, series, range, bck, &stmts, &scy).await; let res = crate::events2::msp::find_ts_msp(&rt, series, range, bck, &stmts, &scy).await;
if tx.send(res.map_err(Into::into)).await.is_err() { if tx.send(res.map_err(Into::into)).await.is_err() {
// TODO count for stats // TODO count for stats
} }
} }
Job::ReadNextValues(job) => { Job::ReadNextValues(job) => {
info!("scylla worker Job::ReadNextValues");
let fut = (job.futgen)(scy.clone(), stmts.clone()); let fut = (job.futgen)(scy.clone(), stmts.clone());
let res = fut.await; let res = fut.await;
if job.tx.send(res.map_err(Into::into)).await.is_err() { if job.tx.send(res.map_err(Into::into)).await.is_err() {
@@ -184,7 +181,6 @@ impl ScyllaWorker {
} }
} }
Job::AccountingReadTs(rt, ts, tx) => { Job::AccountingReadTs(rt, ts, tx) => {
info!("scylla worker Job::AccountingReadTs");
let ks = match &rt { let ks = match &rt {
RetentionTime::Short => &self.scyconf_st.keyspace, RetentionTime::Short => &self.scyconf_st.keyspace,
RetentionTime::Medium => &self.scyconf_mt.keyspace, RetentionTime::Medium => &self.scyconf_mt.keyspace,
+1
View File
@@ -30,6 +30,7 @@ pub async fn dyn_events_stream(
let subq = make_sub_query( let subq = make_sub_query(
ch_conf, ch_conf,
evq.range().clone(), evq.range().clone(),
evq.one_before_range(),
evq.transform().clone(), evq.transform().clone(),
evq.test_do_wasm(), evq.test_do_wasm(),
evq, evq,
+1
View File
@@ -110,6 +110,7 @@ where
item item
} }
} else { } else {
trace!("discarding events len {:?}", ilge - 1);
let mut dummy = item.new_empty(); let mut dummy = item.new_empty();
item.drain_into(&mut dummy, (0, ilge - 1)) item.drain_into(&mut dummy, (0, ilge - 1))
.map_err(|e| format!("{e} unexpected MergeError while remove of items"))?; .map_err(|e| format!("{e} unexpected MergeError while remove of items"))?;
+2 -1
View File
@@ -200,6 +200,7 @@ where
pub fn make_sub_query<SUB>( pub fn make_sub_query<SUB>(
ch_conf: ChannelTypeConfigGen, ch_conf: ChannelTypeConfigGen,
range: SeriesRange, range: SeriesRange,
one_before_range: bool,
transform: TransformQuery, transform: TransformQuery,
test_do_wasm: Option<&str>, test_do_wasm: Option<&str>,
sub: SUB, sub: SUB,
@@ -209,7 +210,7 @@ pub fn make_sub_query<SUB>(
where where
SUB: Into<EventsSubQuerySettings>, SUB: Into<EventsSubQuerySettings>,
{ {
let mut select = EventsSubQuerySelect::new(ch_conf, range, transform); let mut select = EventsSubQuerySelect::new(ch_conf, range, one_before_range, transform);
if let Some(wasm1) = test_do_wasm { if let Some(wasm1) = test_do_wasm {
select.set_wasm1(wasm1.into()); select.set_wasm1(wasm1.into());
} }
+1
View File
@@ -46,6 +46,7 @@ async fn timebinnable_stream(
let subq = make_sub_query( let subq = make_sub_query(
ch_conf, ch_conf,
range.clone().into(), range.clone().into(),
one_before_range,
query.transform().clone(), query.transform().clone(),
query.test_do_wasm(), query.test_do_wasm(),
&query, &query,