Added artifical chunked response slowdown
This commit is contained in:
parent
6a3009df26
commit
c7073c8fbe
3 changed files with 58 additions and 4 deletions
3
Cargo.lock
generated
3
Cargo.lock
generated
|
@ -1,6 +1,6 @@
|
||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 4
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "addr2line"
|
name = "addr2line"
|
||||||
|
@ -223,6 +223,7 @@ dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
|
"http-body",
|
||||||
"itertools 0.14.0",
|
"itertools 0.14.0",
|
||||||
"rand",
|
"rand",
|
||||||
"rand_chacha",
|
"rand_chacha",
|
||||||
|
|
|
@ -10,6 +10,7 @@ axum-server = { version = "0.7.2", features = ["tls-rustls"] }
|
||||||
chrono = "0.4.40"
|
chrono = "0.4.40"
|
||||||
clap = { version = "4.5.37", features = ["derive"] }
|
clap = { version = "4.5.37", features = ["derive"] }
|
||||||
hashbrown = "0.15.2"
|
hashbrown = "0.15.2"
|
||||||
|
http-body = "1.0.1"
|
||||||
itertools = "0.14.0"
|
itertools = "0.14.0"
|
||||||
rand = "0.9.1"
|
rand = "0.9.1"
|
||||||
rand_chacha = "0.9.0"
|
rand_chacha = "0.9.0"
|
||||||
|
|
58
src/main.rs
58
src/main.rs
|
@ -1,21 +1,32 @@
|
||||||
mod generator;
|
mod generator;
|
||||||
|
|
||||||
use axum::{extract::Path, response::Html, routing::get, Router};
|
use axum::{
|
||||||
|
body::{Body, Bytes},
|
||||||
|
extract::Path,
|
||||||
|
response::{Html, IntoResponse, Response},
|
||||||
|
routing::get,
|
||||||
|
Router,
|
||||||
|
};
|
||||||
use axum_server::{bind_rustls, tls_rustls::RustlsConfig};
|
use axum_server::{bind_rustls, tls_rustls::RustlsConfig};
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
|
use http_body::Frame;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use rand::{prelude::*, Rng as _};
|
use rand::{prelude::*, Rng as _};
|
||||||
use rand_chacha::{rand_core::SeedableRng, ChaCha8Rng};
|
use rand_chacha::{rand_core::SeedableRng, ChaCha8Rng};
|
||||||
use std::{
|
use std::{
|
||||||
borrow::Cow,
|
borrow::Cow,
|
||||||
|
convert::Infallible,
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
|
pin::Pin,
|
||||||
sync::{
|
sync::{
|
||||||
atomic::{AtomicU64, Ordering},
|
atomic::{AtomicU64, Ordering},
|
||||||
Arc,
|
Arc,
|
||||||
},
|
},
|
||||||
|
task::{Context, Poll},
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
use tokio::time::{interval, Interval};
|
||||||
|
|
||||||
pub type Rng = ChaCha8Rng;
|
pub type Rng = ChaCha8Rng;
|
||||||
|
|
||||||
|
@ -43,6 +54,42 @@ fn create_rng(seed_bytes: impl IntoIterator<Item = u8>) -> Rng {
|
||||||
|
|
||||||
const COUNT_FILE: &str = "count.txt";
|
const COUNT_FILE: &str = "count.txt";
|
||||||
|
|
||||||
|
const SLOW_CHUNK_SIZE: usize = 50;
|
||||||
|
const SLOW_DURATION: Duration = Duration::from_millis(250);
|
||||||
|
|
||||||
|
struct SlowBody {
|
||||||
|
bytes: Bytes,
|
||||||
|
interval: Interval,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl http_body::Body for SlowBody {
|
||||||
|
type Data = Bytes;
|
||||||
|
type Error = Infallible;
|
||||||
|
|
||||||
|
fn poll_frame(
|
||||||
|
mut self: Pin<&mut Self>,
|
||||||
|
cx: &mut Context<'_>,
|
||||||
|
) -> Poll<Option<Result<Frame<Self::Data>, Self::Error>>> {
|
||||||
|
match self.interval.poll_tick(cx) {
|
||||||
|
Poll::Ready(_) => {
|
||||||
|
if self.bytes.is_empty() {
|
||||||
|
Poll::Ready(None)
|
||||||
|
} else {
|
||||||
|
let split_len = self.bytes.len().min(SLOW_CHUNK_SIZE);
|
||||||
|
Poll::Ready(Some(Ok(Frame::data(self.bytes.split_to(split_len)))))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Poll::Pending => Poll::Pending,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoResponse for SlowBody {
|
||||||
|
fn into_response(self) -> Response {
|
||||||
|
Html(Body::new(self)).into_response()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
|
@ -105,7 +152,7 @@ async fn main() {
|
||||||
content
|
content
|
||||||
});
|
});
|
||||||
|
|
||||||
Html(format!(
|
let html = format!(
|
||||||
"<!DOCTYPE html>
|
"<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
@ -119,7 +166,12 @@ async fn main() {
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>"
|
</html>"
|
||||||
))
|
);
|
||||||
|
|
||||||
|
SlowBody {
|
||||||
|
bytes: html.into(),
|
||||||
|
interval: interval(SLOW_DURATION),
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue