Remove crate items
This commit is contained in:
@@ -8,6 +8,7 @@ use bytes::BufMut;
|
||||
use bytes::BytesMut;
|
||||
use disk::merge::mergedblobsfromremotes::MergedBlobsFromRemotes;
|
||||
use disk::raw::conn::make_local_event_blobs_stream;
|
||||
use futures_util::stream;
|
||||
use futures_util::FutureExt;
|
||||
use futures_util::Stream;
|
||||
use futures_util::StreamExt;
|
||||
@@ -22,6 +23,7 @@ use hyper::Response;
|
||||
use items_0::streamitem::RangeCompletableItem;
|
||||
use items_0::streamitem::Sitemty;
|
||||
use items_0::streamitem::StreamItem;
|
||||
use items_0::WithLen;
|
||||
use items_2::eventfull::EventFull;
|
||||
use itertools::Itertools;
|
||||
use netpod::log::*;
|
||||
@@ -43,7 +45,7 @@ use netpod::APP_JSON;
|
||||
use netpod::APP_OCTET;
|
||||
use parse::channelconfig::extract_matching_config_entry;
|
||||
use parse::channelconfig::read_local_config;
|
||||
use parse::channelconfig::Config;
|
||||
use parse::channelconfig::ChannelConfigs;
|
||||
use parse::channelconfig::ConfigEntry;
|
||||
use parse::channelconfig::MatchingConfigEntry;
|
||||
use query::api4::events::PlainEventsQuery;
|
||||
@@ -641,7 +643,7 @@ pub struct DataApiPython3DataStream {
|
||||
node_config: NodeConfigCached,
|
||||
chan_ix: usize,
|
||||
chan_stream: Option<Pin<Box<dyn Stream<Item = Result<BytesMut, Error>> + Send>>>,
|
||||
config_fut: Option<Pin<Box<dyn Future<Output = Result<Config, Error>> + Send>>>,
|
||||
config_fut: Option<Pin<Box<dyn Future<Output = Result<ChannelConfigs, Error>> + Send>>>,
|
||||
disk_io_tune: DiskIoTune,
|
||||
do_decompress: bool,
|
||||
#[allow(unused)]
|
||||
@@ -689,7 +691,7 @@ impl DataApiPython3DataStream {
|
||||
count_events: &mut usize,
|
||||
) -> Result<BytesMut, Error> {
|
||||
let mut d = BytesMut::new();
|
||||
for i1 in 0..b.tss.len() {
|
||||
for i1 in 0..b.len() {
|
||||
const EVIMAX: usize = 6;
|
||||
if *count_events < EVIMAX {
|
||||
debug!(
|
||||
@@ -811,85 +813,94 @@ impl Stream for DataApiPython3DataStream {
|
||||
Ok(k) => k,
|
||||
Err(e) => return Err(e)?,
|
||||
};
|
||||
let entry = match entry_res {
|
||||
match entry_res {
|
||||
MatchingConfigEntry::None => {
|
||||
return Err(Error::with_public_msg("no config entry found"))?
|
||||
warn!("DataApiPython3DataStream no config entry found for {:?}", config);
|
||||
self.chan_stream = Some(Box::pin(stream::empty()));
|
||||
continue;
|
||||
}
|
||||
MatchingConfigEntry::Multiple => {
|
||||
return Err(Error::with_public_msg("multiple config entries found"))?
|
||||
warn!(
|
||||
"DataApiPython3DataStream multiple config entries found for {:?}",
|
||||
config
|
||||
);
|
||||
self.chan_stream = Some(Box::pin(stream::empty()));
|
||||
continue;
|
||||
}
|
||||
MatchingConfigEntry::Entry(entry) => entry.clone(),
|
||||
};
|
||||
let channel = self.channels[self.chan_ix - 1].clone();
|
||||
debug!("found channel_config for {}: {:?}", channel.name, entry);
|
||||
let evq = PlainEventsQuery::new(channel, self.range.clone()).for_event_blobs();
|
||||
info!("query for event blobs retrieval: evq {evq:?}");
|
||||
warn!("fix magic inmem_bufcap");
|
||||
let perf_opts = PerfOpts::default();
|
||||
// TODO is this a good to place decide this?
|
||||
let s = if self.node_config.node_config.cluster.is_central_storage {
|
||||
info!("Set up central storage stream");
|
||||
// TODO pull up this config
|
||||
let event_chunker_conf = EventChunkerConf::new(ByteSize::kb(1024));
|
||||
let s = make_local_event_blobs_stream(
|
||||
evq.range().try_into()?,
|
||||
evq.channel().clone(),
|
||||
&entry,
|
||||
evq.one_before_range(),
|
||||
self.do_decompress,
|
||||
event_chunker_conf,
|
||||
self.disk_io_tune.clone(),
|
||||
&self.node_config,
|
||||
)?;
|
||||
Box::pin(s) as Pin<Box<dyn Stream<Item = Sitemty<EventFull>> + Send>>
|
||||
} else {
|
||||
if let Some(sh) = &entry.shape {
|
||||
if sh.len() > 1 {
|
||||
warn!("Remote stream fetch for shape {sh:?}");
|
||||
}
|
||||
}
|
||||
debug!("Set up merged remote stream");
|
||||
let s = MergedBlobsFromRemotes::new(
|
||||
evq,
|
||||
perf_opts,
|
||||
self.node_config.node_config.cluster.clone(),
|
||||
);
|
||||
Box::pin(s) as Pin<Box<dyn Stream<Item = Sitemty<EventFull>> + Send>>
|
||||
};
|
||||
let s = s.map({
|
||||
let mut header_out = false;
|
||||
let mut count_events = 0;
|
||||
let channel = self.channels[self.chan_ix - 1].clone();
|
||||
move |b| {
|
||||
let ret = match b {
|
||||
Ok(b) => {
|
||||
let f = match b {
|
||||
StreamItem::DataItem(RangeCompletableItem::Data(b)) => {
|
||||
Self::convert_item(
|
||||
b,
|
||||
&channel,
|
||||
&entry,
|
||||
&mut header_out,
|
||||
&mut count_events,
|
||||
)?
|
||||
}
|
||||
_ => BytesMut::new(),
|
||||
};
|
||||
Ok(f)
|
||||
MatchingConfigEntry::Entry(entry) => {
|
||||
let entry = entry.clone();
|
||||
let channel = self.channels[self.chan_ix - 1].clone();
|
||||
debug!("found channel_config for {}: {:?}", channel.name, entry);
|
||||
let evq = PlainEventsQuery::new(channel, self.range.clone()).for_event_blobs();
|
||||
info!("query for event blobs retrieval: evq {evq:?}");
|
||||
warn!("fix magic inmem_bufcap");
|
||||
let perf_opts = PerfOpts::default();
|
||||
// TODO is this a good to place decide this?
|
||||
let s = if self.node_config.node_config.cluster.is_central_storage {
|
||||
info!("Set up central storage stream");
|
||||
// TODO pull up this config
|
||||
let event_chunker_conf = EventChunkerConf::new(ByteSize::kb(1024));
|
||||
let s = make_local_event_blobs_stream(
|
||||
evq.range().try_into()?,
|
||||
evq.channel().clone(),
|
||||
&entry,
|
||||
evq.one_before_range(),
|
||||
self.do_decompress,
|
||||
event_chunker_conf,
|
||||
self.disk_io_tune.clone(),
|
||||
&self.node_config,
|
||||
)?;
|
||||
Box::pin(s) as Pin<Box<dyn Stream<Item = Sitemty<EventFull>> + Send>>
|
||||
} else {
|
||||
if let Some(sh) = &entry.shape {
|
||||
if sh.len() > 1 {
|
||||
warn!("Remote stream fetch for shape {sh:?}");
|
||||
}
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
debug!("Set up merged remote stream");
|
||||
let s = MergedBlobsFromRemotes::new(
|
||||
evq,
|
||||
perf_opts,
|
||||
self.node_config.node_config.cluster.clone(),
|
||||
);
|
||||
Box::pin(s) as Pin<Box<dyn Stream<Item = Sitemty<EventFull>> + Send>>
|
||||
};
|
||||
ret
|
||||
let s = s.map({
|
||||
let mut header_out = false;
|
||||
let mut count_events = 0;
|
||||
let channel = self.channels[self.chan_ix - 1].clone();
|
||||
move |b| {
|
||||
let ret = match b {
|
||||
Ok(b) => {
|
||||
let f = match b {
|
||||
StreamItem::DataItem(RangeCompletableItem::Data(b)) => {
|
||||
Self::convert_item(
|
||||
b,
|
||||
&channel,
|
||||
&entry,
|
||||
&mut header_out,
|
||||
&mut count_events,
|
||||
)?
|
||||
}
|
||||
_ => BytesMut::new(),
|
||||
};
|
||||
Ok(f)
|
||||
}
|
||||
Err(e) => Err(e),
|
||||
};
|
||||
ret
|
||||
}
|
||||
});
|
||||
//let _ = Box::new(s) as Box<dyn Stream<Item = Result<BytesMut, Error>> + Unpin>;
|
||||
let evm = if self.events_max == 0 {
|
||||
usize::MAX
|
||||
} else {
|
||||
self.events_max as usize
|
||||
};
|
||||
self.chan_stream = Some(Box::pin(s.map_err(Error::from).take(evm)));
|
||||
continue;
|
||||
}
|
||||
});
|
||||
//let _ = Box::new(s) as Box<dyn Stream<Item = Result<BytesMut, Error>> + Unpin>;
|
||||
let evm = if self.events_max == 0 {
|
||||
usize::MAX
|
||||
} else {
|
||||
self.events_max as usize
|
||||
};
|
||||
self.chan_stream = Some(Box::pin(s.map_err(Error::from).take(evm)));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Ready(Err(e)) => {
|
||||
self.config_fut = None;
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
use crate::bodystream::{response, ToPublicResponse};
|
||||
use crate::bodystream::response;
|
||||
use crate::bodystream::ToPublicResponse;
|
||||
use crate::Error;
|
||||
use http::Method;
|
||||
use http::Request;
|
||||
use http::Response;
|
||||
use http::StatusCode;
|
||||
use http::{Method, Request, Response};
|
||||
use hyper::Body;
|
||||
use netpod::log::*;
|
||||
use netpod::ChannelSearchQuery;
|
||||
use netpod::ChannelSearchResult;
|
||||
use netpod::{ChannelSearchQuery, NodeConfigCached};
|
||||
use netpod::{ACCEPT_ALL, APP_JSON};
|
||||
use netpod::NodeConfigCached;
|
||||
use netpod::ACCEPT_ALL;
|
||||
use netpod::APP_JSON;
|
||||
use url::Url;
|
||||
|
||||
pub async fn channel_search(req: Request<Body>, node_config: &NodeConfigCached) -> Result<ChannelSearchResult, Error> {
|
||||
|
||||
@@ -127,6 +127,65 @@ impl ChannelConfigHandler {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ChannelConfigsHandler {}
|
||||
|
||||
impl ChannelConfigsHandler {
|
||||
pub fn handler(req: &Request<Body>) -> Option<Self> {
|
||||
if req.uri().path() == "/api/4/channel/configs" {
|
||||
Some(Self {})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn handle(&self, req: Request<Body>, node_config: &NodeConfigCached) -> Result<Response<Body>, Error> {
|
||||
if req.method() == Method::GET {
|
||||
let accept_def = APP_JSON;
|
||||
let accept = req
|
||||
.headers()
|
||||
.get(http::header::ACCEPT)
|
||||
.map_or(accept_def, |k| k.to_str().unwrap_or(accept_def));
|
||||
if accept.contains(APP_JSON) || accept.contains(ACCEPT_ALL) {
|
||||
match self.channel_configs(req, &node_config).await {
|
||||
Ok(k) => Ok(k),
|
||||
Err(e) => {
|
||||
warn!("ChannelConfigHandler::handle: got error from channel_config: {e:?}");
|
||||
Ok(e.to_public_response())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Ok(response(StatusCode::BAD_REQUEST).body(Body::empty())?)
|
||||
}
|
||||
} else {
|
||||
Ok(response(StatusCode::METHOD_NOT_ALLOWED).body(Body::empty())?)
|
||||
}
|
||||
}
|
||||
|
||||
async fn channel_configs(
|
||||
&self,
|
||||
req: Request<Body>,
|
||||
node_config: &NodeConfigCached,
|
||||
) -> Result<Response<Body>, Error> {
|
||||
info!("channel_configs");
|
||||
let url = Url::parse(&format!("dummy:{}", req.uri()))?;
|
||||
let q = ChannelConfigQuery::from_url(&url)?;
|
||||
info!("channel_configs for q {q:?}");
|
||||
let conf = if let Some(_) = &node_config.node_config.cluster.scylla {
|
||||
return Err(Error::with_msg_no_trace("TODO"));
|
||||
} else if let Some(_) = &node_config.node.channel_archiver {
|
||||
return Err(Error::with_msg_no_trace("TODO"));
|
||||
} else if let Some(_) = &node_config.node.archiver_appliance {
|
||||
return Err(Error::with_msg_no_trace("TODO"));
|
||||
} else {
|
||||
disk::channelconfig::configs(q.channel, node_config).await?
|
||||
};
|
||||
let ret = response(StatusCode::OK)
|
||||
.header(http::header::CONTENT_TYPE, APP_JSON)
|
||||
.body(Body::from(serde_json::to_string(&conf)?))?;
|
||||
Ok(ret)
|
||||
}
|
||||
}
|
||||
|
||||
trait ErrConv<T> {
|
||||
fn err_conv(self) -> Result<T, Error>;
|
||||
}
|
||||
|
||||
@@ -1,24 +1,25 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct Error(pub ::err::Error);
|
||||
pub struct Error(pub err::Error);
|
||||
|
||||
impl Error {
|
||||
pub fn with_msg<S: Into<String>>(s: S) -> Self {
|
||||
Self(::err::Error::with_msg(s))
|
||||
Self(err::Error::with_msg(s))
|
||||
}
|
||||
|
||||
pub fn with_msg_no_trace<S: Into<String>>(s: S) -> Self {
|
||||
Self(::err::Error::with_msg_no_trace(s))
|
||||
Self(err::Error::with_msg_no_trace(s))
|
||||
}
|
||||
|
||||
pub fn with_public_msg<S: Into<String>>(s: S) -> Self {
|
||||
Self(::err::Error::with_public_msg(s))
|
||||
Self(err::Error::with_public_msg(s))
|
||||
}
|
||||
|
||||
pub fn with_public_msg_no_trace<S: Into<String>>(s: S) -> Self {
|
||||
Self(::err::Error::with_public_msg_no_trace(s))
|
||||
Self(err::Error::with_public_msg_no_trace(s))
|
||||
}
|
||||
|
||||
pub fn msg(&self) -> &str {
|
||||
@@ -52,13 +53,13 @@ impl fmt::Display for Error {
|
||||
|
||||
impl std::error::Error for Error {}
|
||||
|
||||
impl From<::err::Error> for Error {
|
||||
fn from(x: ::err::Error) -> Self {
|
||||
impl From<err::Error> for Error {
|
||||
fn from(x: err::Error) -> Self {
|
||||
Self(x)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Error> for ::err::Error {
|
||||
impl From<Error> for err::Error {
|
||||
fn from(x: Error) -> Self {
|
||||
x.0
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ use hyper::Body;
|
||||
use hyper::Request;
|
||||
use hyper::Response;
|
||||
use net::SocketAddr;
|
||||
use netpod::is_false;
|
||||
use netpod::log::*;
|
||||
use netpod::query::prebinned::PreBinnedQuery;
|
||||
use netpod::NodeConfigCached;
|
||||
@@ -297,6 +298,8 @@ async fn http_service_inner(
|
||||
h.handle(req, &node_config).await
|
||||
} else if let Some(h) = api4::binned::BinnedHandler::handler(&req) {
|
||||
h.handle(req, &node_config).await
|
||||
} else if let Some(h) = channelconfig::ChannelConfigsHandler::handler(&req) {
|
||||
h.handle(req, &node_config).await
|
||||
} else if let Some(h) = channelconfig::ChannelConfigHandler::handler(&req) {
|
||||
h.handle(req, &node_config).await
|
||||
} else if let Some(h) = channelconfig::ScyllaChannelsWithType::handler(&req) {
|
||||
@@ -607,9 +610,9 @@ pub struct StatusBoardEntry {
|
||||
ts_created: SystemTime,
|
||||
#[serde(serialize_with = "instant_serde::ser")]
|
||||
ts_updated: SystemTime,
|
||||
#[serde(skip_serializing_if = "items_2::bool_is_false")]
|
||||
#[serde(skip_serializing_if = "is_false")]
|
||||
is_error: bool,
|
||||
#[serde(skip_serializing_if = "items_2::bool_is_false")]
|
||||
#[serde(skip_serializing_if = "is_false")]
|
||||
is_ok: bool,
|
||||
#[serde(skip_serializing_if = "Vec::is_empty")]
|
||||
errors: Vec<Error>,
|
||||
|
||||
Reference in New Issue
Block a user