WIP on json endpoint
This commit is contained in:
@@ -1,11 +1,7 @@
|
||||
use crate::agg::binnedt::IntoBinnedT;
|
||||
use crate::agg::eventbatch::MinMaxAvgScalarEventBatchStreamItem;
|
||||
use crate::agg::scalarbinbatch::{MinMaxAvgScalarBinBatch, MinMaxAvgScalarBinBatchStreamItem};
|
||||
use crate::binnedstream::{BinnedStreamFromMerged, BinnedStreamFromPreBinnedPatches};
|
||||
use crate::agg::scalarbinbatch::MinMaxAvgScalarBinBatch;
|
||||
use crate::cache::pbv::PreBinnedValueByteStream;
|
||||
use crate::cache::pbvfs::PreBinnedItem;
|
||||
use crate::channelconfig::{extract_matching_config_entry, read_local_config};
|
||||
use crate::frame::makeframe::make_frame;
|
||||
use crate::merge::MergedMinMaxAvgScalarStream;
|
||||
use crate::raw::EventsQuery;
|
||||
use bytes::Bytes;
|
||||
@@ -15,8 +11,7 @@ use futures_core::Stream;
|
||||
use futures_util::{pin_mut, StreamExt};
|
||||
use hyper::Response;
|
||||
use netpod::{
|
||||
AggKind, BinnedRange, ByteSize, Channel, Cluster, NanoRange, NodeConfigCached, PerfOpts, PreBinnedPatchCoord,
|
||||
PreBinnedPatchIterator, PreBinnedPatchRange, ToNanos,
|
||||
AggKind, ByteSize, Channel, Cluster, NanoRange, NodeConfigCached, PerfOpts, PreBinnedPatchCoord, ToNanos,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::BTreeMap;
|
||||
@@ -90,6 +85,30 @@ impl BinnedQuery {
|
||||
info!("BinnedQuery::from_request {:?}", ret);
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
pub fn range(&self) -> &NanoRange {
|
||||
&self.range
|
||||
}
|
||||
|
||||
pub fn channel(&self) -> &Channel {
|
||||
&self.channel
|
||||
}
|
||||
|
||||
pub fn bin_count(&self) -> u64 {
|
||||
self.bin_count
|
||||
}
|
||||
|
||||
pub fn agg_kind(&self) -> &AggKind {
|
||||
&self.agg_kind
|
||||
}
|
||||
|
||||
pub fn cache_usage(&self) -> &CacheUsage {
|
||||
&self.cache_usage
|
||||
}
|
||||
|
||||
pub fn disk_stats_every(&self) -> &ByteSize {
|
||||
&self.disk_stats_every
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -195,119 +214,6 @@ fn cache_usage_from_params(params: &BTreeMap<String, String>) -> Result<CacheUsa
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
type BinnedStreamBox = Pin<Box<dyn Stream<Item = Result<Bytes, Error>> + Send>>;
|
||||
|
||||
pub async fn binned_bytes_for_http(
|
||||
node_config: &NodeConfigCached,
|
||||
query: &BinnedQuery,
|
||||
) -> Result<BinnedStreamBox, Error> {
|
||||
if query.channel.backend != node_config.node.backend {
|
||||
let err = Error::with_msg(format!(
|
||||
"backend mismatch node: {} requested: {}",
|
||||
node_config.node.backend, query.channel.backend
|
||||
));
|
||||
return Err(err);
|
||||
}
|
||||
let range = &query.range;
|
||||
let channel_config = read_local_config(&query.channel, &node_config.node).await?;
|
||||
let entry = extract_matching_config_entry(range, &channel_config);
|
||||
info!("binned_bytes_for_http found config entry {:?}", entry);
|
||||
let range = BinnedRange::covering_range(range.clone(), query.bin_count).ok_or(Error::with_msg(format!(
|
||||
"binned_bytes_for_http BinnedRange::covering_range returned None"
|
||||
)))?;
|
||||
let perf_opts = PerfOpts { inmem_bufcap: 512 };
|
||||
match PreBinnedPatchRange::covering_range(query.range.clone(), query.bin_count) {
|
||||
Some(pre_range) => {
|
||||
info!("binned_bytes_for_http found pre_range: {:?}", pre_range);
|
||||
if range.grid_spec.bin_t_len() < pre_range.grid_spec.bin_t_len() {
|
||||
let msg = format!(
|
||||
"binned_bytes_for_http incompatible ranges:\npre_range: {:?}\nrange: {:?}",
|
||||
pre_range, range
|
||||
);
|
||||
return Err(Error::with_msg(msg));
|
||||
}
|
||||
let s1 = BinnedStreamFromPreBinnedPatches::new(
|
||||
PreBinnedPatchIterator::from_range(pre_range),
|
||||
query.channel.clone(),
|
||||
range,
|
||||
query.agg_kind.clone(),
|
||||
query.cache_usage.clone(),
|
||||
node_config,
|
||||
query.disk_stats_every.clone(),
|
||||
)?;
|
||||
let ret = BinnedBytesForHttpStream::new(s1);
|
||||
Ok(Box::pin(ret))
|
||||
}
|
||||
None => {
|
||||
info!(
|
||||
"binned_bytes_for_http no covering range for prebinned, merge from remotes instead {:?}",
|
||||
range
|
||||
);
|
||||
let evq = EventsQuery {
|
||||
channel: query.channel.clone(),
|
||||
range: query.range.clone(),
|
||||
agg_kind: query.agg_kind.clone(),
|
||||
};
|
||||
// TODO do I need to set up more transformations or binning to deliver the requested data?
|
||||
let s1 = MergedFromRemotes::new(evq, perf_opts, node_config.node_config.cluster.clone());
|
||||
let s1 = s1.into_binned_t(range);
|
||||
let s1 = BinnedStreamFromMerged::new(Box::pin(s1))?;
|
||||
let ret = BinnedBytesForHttpStream::new(s1);
|
||||
Ok(Box::pin(ret))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type BinnedBytesForHttpStreamFrame = <BinnedStreamFromPreBinnedPatches as Stream>::Item;
|
||||
|
||||
pub struct BinnedBytesForHttpStream<S> {
|
||||
inp: S,
|
||||
errored: bool,
|
||||
completed: bool,
|
||||
}
|
||||
|
||||
impl<S> BinnedBytesForHttpStream<S> {
|
||||
pub fn new(inp: S) -> Self {
|
||||
Self {
|
||||
inp,
|
||||
errored: false,
|
||||
completed: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> Stream for BinnedBytesForHttpStream<S>
|
||||
where
|
||||
S: Stream<Item = Result<MinMaxAvgScalarBinBatchStreamItem, Error>> + Unpin,
|
||||
{
|
||||
type Item = Result<Bytes, Error>;
|
||||
|
||||
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
|
||||
use Poll::*;
|
||||
if self.completed {
|
||||
panic!("BinnedBytesForHttpStream poll_next on completed");
|
||||
}
|
||||
if self.errored {
|
||||
self.completed = true;
|
||||
return Ready(None);
|
||||
}
|
||||
match self.inp.poll_next_unpin(cx) {
|
||||
Ready(Some(item)) => match make_frame::<BinnedBytesForHttpStreamFrame>(&item) {
|
||||
Ok(buf) => Ready(Some(Ok(buf.freeze()))),
|
||||
Err(e) => {
|
||||
self.errored = true;
|
||||
Ready(Some(Err(e.into())))
|
||||
}
|
||||
},
|
||||
Ready(None) => {
|
||||
self.completed = true;
|
||||
Ready(None)
|
||||
}
|
||||
Pending => Pending,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE This answers a request for a single valid pre-binned patch.
|
||||
// A user must first make sure that the grid spec is valid, and that this node is responsible for it.
|
||||
// Otherwise it is an error.
|
||||
|
||||
Reference in New Issue
Block a user