Initial Dever 0.0.1

This commit is contained in:
Codex committed 2026-11-03 03:32:07 +00:00
commit 81233d098c
1479 files changed
+163782

No files matched your search

+258
View File
@@ -0,0 +1,258 @@
use dever_runtime::wire::serde::{self, Deserialize, Serialize};
use dever_runtime::{
api::{Request, Response},
task::{Limits, Runtime, Scope},
};
use std::future::Future;
struct Input<'scope> {
request: Request,
peer: std::net::SocketAddr,
scope: &'scope Scope<'scope>,
}
fn fault(_: impl std::fmt::Display) -> Fault {
&FaultInfo {
message: "HTTP input failure",
source: "api-reference",
line: 1,
column: 1,
}
}
// 此样例不挂起;直接轮询实际生成入口,计时不含网络与调度器启动。
fn generated(values: &[Input<'_>]) -> Result<Vec<u8>, Fault> {
let Some(value) = values.first() else {
return Ok(Vec::new());
};
let future = async {
if value.request.uri().path() == "/bench/wire/count" {
GENERATED_LIST(&value.request, value.peer, value.scope).await
} else {
GENERATED_HTTP(&value.request, value.peer, value.scope).await
}
};
let mut future = std::pin::pin!(future);
let mut context = std::task::Context::from_waker(std::task::Waker::noop());
let std::task::Poll::Ready(response) = future.as_mut().poll(&mut context) else {
panic!("pure HTTP fixture unexpectedly suspended");
};
if response.status() != 200 {
return Err(fault(response.status()));
}
Ok(response.into_body().into())
}
#[derive(Deserialize, Serialize)]
#[serde(crate = "dever_runtime::wire::serde", deny_unknown_fields)]
struct Payload {
text: String,
value: i64,
}
#[derive(Deserialize)]
#[serde(crate = "dever_runtime::wire::serde", deny_unknown_fields)]
struct Arguments {
payload: Object<Payload>,
}
#[derive(Deserialize)]
#[serde(crate = "dever_runtime::wire::serde", deny_unknown_fields)]
struct ListArguments {
values: Integers,
}
struct Integers(Vec<i64>);
impl<'input> Deserialize<'input> for Integers {
fn deserialize<Decoder: serde::Deserializer<'input>>(
decoder: Decoder,
) -> Result<Self, Decoder::Error> {
struct Visitor;
impl<'input> serde::de::Visitor<'input> for Visitor {
type Value = Integers;
fn expecting(&self, output: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
output.write_str("an integer array")
}
fn visit_seq<Access: serde::de::SeqAccess<'input>>(
self,
mut access: Access,
) -> Result<Integers, Access::Error> {
let mut values = Vec::new();
while let Some(value) = access.next_element()? {
// 根对象和数组各占一个值;检查与 Serde 解码在同一次遍历中完成。
if values.len() == 65536 - 2 {
return Err(serde::de::Error::custom("value limit"));
}
values.push(value);
}
Ok(Integers(values))
}
}
decoder.deserialize_seq(Visitor)
}
}
struct Object<Value>(Value);
impl<'input, Value: Deserialize<'input>> Deserialize<'input> for Object<Value> {
fn deserialize<Decoder: serde::Deserializer<'input>>(
decoder: Decoder,
) -> Result<Self, Decoder::Error> {
struct Visitor<Value>(std::marker::PhantomData<Value>);
impl<'input, Value: Deserialize<'input>> serde::de::Visitor<'input> for Visitor<Value> {
type Value = Value;
fn expecting(&self, output: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
output.write_str("an object")
}
fn visit_map<Access: serde::de::MapAccess<'input>>(
self,
access: Access,
) -> Result<Value, Access::Error> {
Value::deserialize(serde::de::value::MapAccessDeserializer::new(access))
}
}
decoder
.deserialize_map(Visitor(std::marker::PhantomData))
.map(Self)
}
}
// 独立使用 Serde;固定记录保证结构预算,字节预算在唯一输入/输出边界处理。
fn reference(values: &[Input<'_>]) -> Result<Vec<u8>, Fault> {
let Some(value) = values.first() else {
return Ok(Vec::new());
};
let request = &value.request;
let mut headers = request.headers().get_all("content-type").iter();
let content = headers.next().ok_or_else(|| fault("content type"))?;
let content = std::str::from_utf8(content.as_bytes()).map_err(fault)?;
if !content
.split(';')
.next()
.unwrap()
.trim()
.eq_ignore_ascii_case("application/json")
|| headers.next().is_some()
{
return Err(fault("content type"));
}
if request.body().len() > 16 * 1024 * 1024 {
return Err(fault("input size"));
}
let text = std::str::from_utf8(request.body()).map_err(fault)?;
#[derive(Serialize)]
#[serde(crate = "dever_runtime::wire::serde")]
struct Envelope<Value> {
code: u16,
message: &'static str,
data: Value,
}
struct Output(Vec<u8>);
impl std::io::Write for Output {
fn write(&mut self, bytes: &[u8]) -> std::io::Result<usize> {
if bytes.len() > 16 * 1024 * 1024 - self.0.len() {
return Err(std::io::Error::other("output size"));
}
self.0.extend_from_slice(bytes);
Ok(bytes.len())
}
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
}
let mut output = Output(Vec::with_capacity(128));
if request.uri().path() == "/bench/wire/count" {
let arguments: Object<ListArguments> = serde_json::from_str(text).map_err(fault)?;
serde_json::to_writer(
&mut output,
&Envelope {
code: 0,
message: "ok",
data: arguments.0.values.0.len() as i64,
},
)
.map_err(fault)?;
} else {
let arguments: Object<Arguments> = serde_json::from_str(text).map_err(fault)?;
serde_json::to_writer(
&mut output,
&Envelope {
code: 0,
message: "ok",
data: arguments.0.payload.0,
},
)
.map_err(fault)?;
}
let mut response = Response::new(output.0.into());
response.headers_mut().insert(
hyper::header::CONTENT_TYPE,
hyper::header::HeaderValue::from_static("application/json; charset=utf-8"),
);
Ok(response.into_body().into())
}
fn main() {
println!("case,sample,implementation,elapsed_ns,checksum");
let runtime = Runtime::new(Limits {
threads: 1,
workers: 1,
tasks: 8,
})
.unwrap();
runtime
.run(async |scope| {
for size in [64, 4096, 65536] {
let payload = Payload {
text: "雪\\\"".repeat(size / 5),
value: 42,
};
let body = format!(
"{{\"payload\":{}}}",
serde_json::to_string(&payload).unwrap()
)
.into_bytes();
let values = [Input {
request: hyper::Request::builder()
.method("POST")
.uri("/bench/wire/echo")
.header("content-type", "application/json")
.body(body.into())
.unwrap(),
peer: ([127, 0, 0, 1], 12345).into(),
scope,
}];
compare(
&format!("http_fixed_record_{size}"),
&values,
200,
generated,
reference,
|body| body.len() as u64,
);
}
for size in [16, 1024, 8192, 32768] {
let body = format!("{{\"values\":[{}]}}", vec!["42"; size].join(",")).into_bytes();
let values = [Input {
request: hyper::Request::builder()
.method("POST")
.uri("/bench/wire/count")
.header("content-type", "application/json")
.body(body.into())
.unwrap(),
peer: ([127, 0, 0, 1], 12345).into(),
scope,
}];
compare(
&format!("http_integer_list_{size}"),
&values,
200,
generated,
reference,
|body| body.len() as u64,
);
}
})
.unwrap();
}