Add remaining types, add docs
This commit is contained in:
@@ -2595,8 +2595,8 @@ impl CaConn {
|
||||
}
|
||||
|
||||
fn log_queues_summary(&self) {
|
||||
self.iqdqs.log_summary();
|
||||
self.iqsp.log_summary();
|
||||
trace!("{}", self.iqdqs.summary());
|
||||
trace!("{}", self.iqsp.summary());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ use async_channel::Sender;
|
||||
use async_channel::WeakSender;
|
||||
use axum::extract::Query;
|
||||
use axum::http;
|
||||
use axum::http::HeaderMap;
|
||||
use axum::response::IntoResponse;
|
||||
use axum::response::Response;
|
||||
use bytes::Bytes;
|
||||
@@ -388,9 +389,11 @@ fn make_routes(
|
||||
"/v1",
|
||||
post({
|
||||
let rres = rres.clone();
|
||||
move |(params, body): (Query<HashMap<String, String>>, axum::body::Body)| {
|
||||
ingest::post_v01((params, body), rres)
|
||||
}
|
||||
move |(headers, params, body): (
|
||||
HeaderMap,
|
||||
Query<HashMap<String, String>>,
|
||||
axum::body::Body,
|
||||
)| { ingest::post_v01((headers, params, body), rres) }
|
||||
}),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,105 +1,317 @@
|
||||
use super::RoutesResources;
|
||||
use axum::extract::FromRequest;
|
||||
use axum::extract::Query;
|
||||
use axum::http::HeaderMap;
|
||||
use axum::Json;
|
||||
use bytes::Bytes;
|
||||
use core::fmt;
|
||||
use err::thiserror;
|
||||
use err::ThisError;
|
||||
use futures_util::StreamExt;
|
||||
use futures_util::TryStreamExt;
|
||||
use items_2::eventsdim0::EventsDim0;
|
||||
use items_2::eventsdim0::EventsDim0NoPulse;
|
||||
use items_2::eventsdim1::EventsDim1;
|
||||
use items_2::eventsdim1::EventsDim1NoPulse;
|
||||
use netpod::log::*;
|
||||
use netpod::ScalarType;
|
||||
use netpod::Shape;
|
||||
use netpod::TsNano;
|
||||
use netpod::APP_CBOR_FRAMED;
|
||||
use scywr::insertqueues::InsertDeques;
|
||||
use scywr::iteminsertqueue::ArrayValue;
|
||||
use scywr::iteminsertqueue::DataValue;
|
||||
use scywr::iteminsertqueue::QueryItem;
|
||||
use scywr::iteminsertqueue::ScalarValue;
|
||||
use serde::Deserialize;
|
||||
use serieswriter::writer::SeriesWriter;
|
||||
use std::collections::HashMap;
|
||||
use std::collections::VecDeque;
|
||||
use std::io::Cursor;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use std::time::SystemTime;
|
||||
use streams::framed_bytes::FramedBytesStream;
|
||||
use taskrun::tokio::time::timeout;
|
||||
// use core::io::BorrowedBuf;
|
||||
|
||||
#[allow(unused)]
|
||||
macro_rules! debug_setup {
|
||||
($($arg:tt)*) => {
|
||||
if true {
|
||||
info!($($arg)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
macro_rules! trace_input {
|
||||
($($arg:tt)*) => {
|
||||
if false {
|
||||
trace!($($arg)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
macro_rules! trace_queues {
|
||||
($($arg:tt)*) => {
|
||||
if false {
|
||||
trace!($($arg)*);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Debug, ThisError)]
|
||||
pub enum Error {
|
||||
UnsupportedContentType,
|
||||
Logic,
|
||||
SeriesWriter(#[from] serieswriter::writer::Error),
|
||||
MissingChannelName,
|
||||
MissingScalarType,
|
||||
MissingShape,
|
||||
SendError,
|
||||
Decode,
|
||||
FramedBytes(#[from] streams::framed_bytes::Error),
|
||||
InsertQueues(#[from] scywr::insertqueues::Error),
|
||||
Serde(#[from] serde_json::Error),
|
||||
#[error("Parse({0})")]
|
||||
Parse(String),
|
||||
NotSupported,
|
||||
}
|
||||
|
||||
struct BodyRead {}
|
||||
|
||||
pub async fn post_v01(
|
||||
(Query(params), body): (Query<HashMap<String, String>>, axum::body::Body),
|
||||
(headers, Query(params), body): (HeaderMap, Query<HashMap<String, String>>, axum::body::Body),
|
||||
rres: Arc<RoutesResources>,
|
||||
) -> Json<serde_json::Value> {
|
||||
match post_v01_try(params, body, rres).await {
|
||||
match post_v01_try(headers, params, body, rres).await {
|
||||
Ok(k) => k,
|
||||
Err(e) => Json(serde_json::Value::String(e.to_string())),
|
||||
Err(e) => Json(serde_json::json!({
|
||||
"error": e.to_string(),
|
||||
})),
|
||||
}
|
||||
}
|
||||
|
||||
async fn post_v01_try(
|
||||
headers: HeaderMap,
|
||||
params: HashMap<String, String>,
|
||||
body: axum::body::Body,
|
||||
rres: Arc<RoutesResources>,
|
||||
) -> Result<Json<serde_json::Value>, Error> {
|
||||
info!("params {:?}", params);
|
||||
if let Some(ct) = headers.get("content-type") {
|
||||
if let Ok(s) = ct.to_str() {
|
||||
if s == APP_CBOR_FRAMED {
|
||||
} else {
|
||||
return Err(Error::UnsupportedContentType);
|
||||
}
|
||||
} else {
|
||||
return Err(Error::UnsupportedContentType);
|
||||
}
|
||||
} else {
|
||||
return Err(Error::UnsupportedContentType);
|
||||
};
|
||||
debug_setup!("params {:?}", params);
|
||||
let stnow = SystemTime::now();
|
||||
let worker_tx = rres.worker_tx.clone();
|
||||
let backend = rres.backend.clone();
|
||||
let channel = params.get("channelName").ok_or(Error::MissingChannelName)?.into();
|
||||
let scalar_type = ScalarType::I16;
|
||||
let shape = Shape::Scalar;
|
||||
info!("establishing...");
|
||||
let mut writer = SeriesWriter::establish(worker_tx, backend, channel, scalar_type, shape, stnow).await?;
|
||||
|
||||
let s = params.get("scalarType").ok_or(Error::MissingScalarType)?;
|
||||
let scalar_type = ScalarType::from_variant_str(&s).map_err(|e| Error::Parse(e.to_string()))?;
|
||||
let shape: Shape = serde_json::from_str(params.get("shape").map_or("[]", |x| x.as_str()))?;
|
||||
debug_setup!("parsed scalar_type {scalar_type:?}");
|
||||
debug_setup!("parsed shape {shape:?}");
|
||||
debug_setup!(
|
||||
"establishing series writer for {:?} {:?} {:?}",
|
||||
channel,
|
||||
scalar_type,
|
||||
shape
|
||||
);
|
||||
let mut writer =
|
||||
SeriesWriter::establish(worker_tx, backend, channel, scalar_type.clone(), shape.clone(), stnow).await?;
|
||||
debug_setup!("series writer established");
|
||||
let mut iqdqs = InsertDeques::new();
|
||||
let mut iqtx = rres.iqtx.clone();
|
||||
// iqtx.send_all(&mut iqdqs).await.map_err(|_| Error::SendError)?;
|
||||
// let deque = &mut iqdqs.st_rf3_rx;
|
||||
|
||||
let mut frames = FramedBytesStream::new(body.into_data_stream().map_err(|_| streams::framed_bytes::Error::Logic));
|
||||
while let Some(frame) = frames.try_next().await? {
|
||||
info!("got frame len {}", frame.len());
|
||||
let evs: EventsDim0<i16> = ciborium::de::from_reader(Cursor::new(frame)).map_err(|_| Error::Decode)?;
|
||||
info!("see events {:?}", evs);
|
||||
loop {
|
||||
let x = timeout(Duration::from_millis(2000), frames.try_next()).await;
|
||||
let x = match x {
|
||||
Ok(x) => x,
|
||||
Err(_) => {
|
||||
tick_writers(&mut writer, &mut iqdqs)?;
|
||||
continue;
|
||||
}
|
||||
};
|
||||
let frame = match x? {
|
||||
Some(x) => x,
|
||||
None => {
|
||||
trace!("input stream done");
|
||||
break;
|
||||
}
|
||||
};
|
||||
trace_input!("got frame len {}", frame.len());
|
||||
let deque = &mut iqdqs.st_rf3_rx;
|
||||
for (i, (&ts, &val)) in evs.tss.iter().zip(evs.values.iter()).enumerate() {
|
||||
info!("ev {:6} {:20} {:20}", i, ts, val);
|
||||
let val = DataValue::Scalar(ScalarValue::I16(val));
|
||||
writer.write(TsNano::from_ns(ts), TsNano::from_ns(ts), val, deque)?;
|
||||
match &shape {
|
||||
Shape::Scalar => match &scalar_type {
|
||||
ScalarType::U8 => {
|
||||
evpush_dim0::<u8, _>(&frame, deque, &mut writer, |x| {
|
||||
DataValue::Scalar(ScalarValue::U8(x as _))
|
||||
})?;
|
||||
}
|
||||
ScalarType::U16 => {
|
||||
evpush_dim0::<u16, _>(&frame, deque, &mut writer, |x| {
|
||||
DataValue::Scalar(ScalarValue::U16(x as _))
|
||||
})?;
|
||||
}
|
||||
ScalarType::U32 => {
|
||||
evpush_dim0::<u32, _>(&frame, deque, &mut writer, |x| {
|
||||
DataValue::Scalar(ScalarValue::U32(x as _))
|
||||
})?;
|
||||
}
|
||||
ScalarType::U64 => {
|
||||
evpush_dim0::<u64, _>(&frame, deque, &mut writer, |x| {
|
||||
DataValue::Scalar(ScalarValue::U64(x as _))
|
||||
})?;
|
||||
}
|
||||
ScalarType::I8 => {
|
||||
evpush_dim0::<i8, _>(&frame, deque, &mut writer, |x| DataValue::Scalar(ScalarValue::I8(x)))?;
|
||||
}
|
||||
ScalarType::I16 => {
|
||||
evpush_dim0::<i16, _>(&frame, deque, &mut writer, |x| DataValue::Scalar(ScalarValue::I16(x)))?;
|
||||
}
|
||||
ScalarType::I32 => {
|
||||
evpush_dim0::<i32, _>(&frame, deque, &mut writer, |x| DataValue::Scalar(ScalarValue::I32(x)))?;
|
||||
}
|
||||
ScalarType::I64 => {
|
||||
evpush_dim0::<i64, _>(&frame, deque, &mut writer, |x| DataValue::Scalar(ScalarValue::I64(x)))?;
|
||||
}
|
||||
ScalarType::F32 => {
|
||||
evpush_dim0::<f32, _>(&frame, deque, &mut writer, |x| DataValue::Scalar(ScalarValue::F32(x)))?;
|
||||
}
|
||||
ScalarType::F64 => {
|
||||
evpush_dim0::<f64, _>(&frame, deque, &mut writer, |x| DataValue::Scalar(ScalarValue::F64(x)))?;
|
||||
}
|
||||
ScalarType::BOOL => return Err(Error::NotSupported),
|
||||
ScalarType::STRING => {
|
||||
evpush_dim0::<String, _>(&frame, deque, &mut writer, |x| {
|
||||
DataValue::Scalar(ScalarValue::String(x))
|
||||
})?;
|
||||
}
|
||||
ScalarType::Enum => return Err(Error::NotSupported),
|
||||
ScalarType::ChannelStatus => return Err(Error::NotSupported),
|
||||
},
|
||||
Shape::Wave(_) => match &scalar_type {
|
||||
ScalarType::U8 => {
|
||||
evpush_dim1::<u8, _>(&frame, deque, &mut writer, |x| DataValue::Array(ArrayValue::U8(x)))?;
|
||||
}
|
||||
ScalarType::U16 => {
|
||||
evpush_dim1::<u16, _>(&frame, deque, &mut writer, |x| DataValue::Array(ArrayValue::U16(x)))?;
|
||||
}
|
||||
ScalarType::U32 => {
|
||||
evpush_dim1::<u32, _>(&frame, deque, &mut writer, |x| DataValue::Array(ArrayValue::U32(x)))?;
|
||||
}
|
||||
ScalarType::U64 => {
|
||||
evpush_dim1::<u64, _>(&frame, deque, &mut writer, |x| DataValue::Array(ArrayValue::U64(x)))?;
|
||||
}
|
||||
ScalarType::I8 => {
|
||||
evpush_dim1::<i8, _>(&frame, deque, &mut writer, |x| DataValue::Array(ArrayValue::I8(x)))?;
|
||||
}
|
||||
ScalarType::I16 => {
|
||||
evpush_dim1::<i16, _>(&frame, deque, &mut writer, |x| DataValue::Array(ArrayValue::I16(x)))?;
|
||||
}
|
||||
ScalarType::I32 => {
|
||||
evpush_dim1::<i32, _>(&frame, deque, &mut writer, |x| DataValue::Array(ArrayValue::I32(x)))?;
|
||||
}
|
||||
ScalarType::I64 => {
|
||||
evpush_dim1::<i64, _>(&frame, deque, &mut writer, |x| DataValue::Array(ArrayValue::I64(x)))?;
|
||||
}
|
||||
ScalarType::F32 => {
|
||||
evpush_dim1::<f32, _>(&frame, deque, &mut writer, |x| DataValue::Array(ArrayValue::F32(x)))?;
|
||||
}
|
||||
ScalarType::F64 => {
|
||||
evpush_dim1::<f64, _>(&frame, deque, &mut writer, |x| DataValue::Array(ArrayValue::F64(x)))?;
|
||||
}
|
||||
ScalarType::BOOL => return Err(Error::NotSupported),
|
||||
ScalarType::STRING => return Err(Error::NotSupported),
|
||||
ScalarType::Enum => return Err(Error::NotSupported),
|
||||
ScalarType::ChannelStatus => return Err(Error::NotSupported),
|
||||
},
|
||||
Shape::Image(_, _) => return Err(Error::NotSupported),
|
||||
}
|
||||
iqtx.send_all(&mut iqdqs).await.map_err(|_| Error::SendError)?;
|
||||
trace_queues!("frame send_all begin {} {}", iqdqs.summary(), iqtx.summary());
|
||||
iqtx.send_all(&mut iqdqs).await?;
|
||||
trace_queues!("frame send_all done {} {}", iqdqs.summary(), iqtx.summary());
|
||||
tick_writers(&mut writer, &mut iqdqs)?;
|
||||
trace_queues!("frame tick_writers done {} {}", iqdqs.summary(), iqtx.summary());
|
||||
}
|
||||
|
||||
let deque = &mut iqdqs.st_rf3_rx;
|
||||
finish_writers(vec![&mut writer], deque)?;
|
||||
iqtx.send_all(&mut iqdqs).await.map_err(|_| Error::SendError)?;
|
||||
trace_queues!("after send_all begin {} {}", iqdqs.summary(), iqtx.summary());
|
||||
iqtx.send_all(&mut iqdqs).await?;
|
||||
trace_queues!("after send_all done {} {}", iqdqs.summary(), iqtx.summary());
|
||||
finish_writers(&mut writer, &mut iqdqs)?;
|
||||
trace_queues!("after finish_writers done {} {}", iqdqs.summary(), iqtx.summary());
|
||||
|
||||
let ret = Json(serde_json::json!({
|
||||
"result": true,
|
||||
}));
|
||||
let ret = Json(serde_json::json!({}));
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
fn tick_writers(sws: Vec<&mut SeriesWriter>, deque: &mut VecDeque<QueryItem>) -> Result<(), Error> {
|
||||
for sw in sws {
|
||||
sw.tick(deque)?;
|
||||
fn evpush_dim0<T, F1>(
|
||||
frame: &Bytes,
|
||||
deque: &mut VecDeque<QueryItem>,
|
||||
writer: &mut SeriesWriter,
|
||||
f1: F1,
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
T: for<'a> Deserialize<'a> + fmt::Debug + Clone,
|
||||
F1: Fn(T) -> DataValue,
|
||||
{
|
||||
let evs: EventsDim0NoPulse<T> = ciborium::de::from_reader(Cursor::new(frame))
|
||||
.map_err(|e| {
|
||||
error!("cbor decode error {e}");
|
||||
})
|
||||
.map_err(|_| Error::Decode)?;
|
||||
let evs: EventsDim0<T> = evs.into();
|
||||
trace_input!("see events {:?}", evs);
|
||||
for (i, (&ts, val)) in evs.tss.iter().zip(evs.values.iter()).enumerate() {
|
||||
let val = val.clone();
|
||||
trace_input!("ev {:6} {:20} {:20?}", i, ts, val);
|
||||
let val = f1(val);
|
||||
writer.write(TsNano::from_ns(ts), TsNano::from_ns(ts), val, deque)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn finish_writers(sws: Vec<&mut SeriesWriter>, deque: &mut VecDeque<QueryItem>) -> Result<(), Error> {
|
||||
for sw in sws {
|
||||
sw.tick(deque)?;
|
||||
fn evpush_dim1<T, F1>(
|
||||
frame: &Bytes,
|
||||
deque: &mut VecDeque<QueryItem>,
|
||||
writer: &mut SeriesWriter,
|
||||
f1: F1,
|
||||
) -> Result<(), Error>
|
||||
where
|
||||
T: for<'a> Deserialize<'a> + fmt::Debug + Clone,
|
||||
F1: Fn(Vec<T>) -> DataValue,
|
||||
{
|
||||
let evs: EventsDim1NoPulse<T> = ciborium::de::from_reader(Cursor::new(frame))
|
||||
.map_err(|e| {
|
||||
error!("cbor decode error {e}");
|
||||
})
|
||||
.map_err(|_| Error::Decode)?;
|
||||
let evs: EventsDim1<T> = evs.into();
|
||||
trace_input!("see events {:?}", evs);
|
||||
for (i, (&ts, val)) in evs.tss.iter().zip(evs.values.iter()).enumerate() {
|
||||
let val = val.clone();
|
||||
trace_input!("ev {:6} {:20} {:20?}", i, ts, val);
|
||||
let val = f1(val);
|
||||
writer.write(TsNano::from_ns(ts), TsNano::from_ns(ts), val, deque)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn tick_writers(writer: &mut SeriesWriter, deque: &mut InsertDeques) -> Result<(), Error> {
|
||||
writer.tick(&mut deque.st_rf3_rx)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn finish_writers(writer: &mut SeriesWriter, deque: &mut InsertDeques) -> Result<(), Error> {
|
||||
writer.tick(&mut deque.st_rf3_rx)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user