Skip to content
This repository was archived by the owner on Mar 24, 2026. It is now read-only.

Commit 7dcfdbd

Browse files
authored
ntex: Cleanups and optimizations (#10612)
1 parent 9069a49 commit 7dcfdbd

5 files changed

Lines changed: 67 additions & 70 deletions

File tree

frameworks/Rust/ntex/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ neon = ["ntex/neon-polling"]
6767
neon-uring = ["ntex/neon-uring"]
6868

6969
[dependencies]
70-
ntex = "3.0.0-pre.11"
71-
ntex-bytes = { version = "1.2", features=["simd"] }
70+
ntex = "3.0.0-pre.13"
71+
ntex-bytes = { version = "1.4", features=["simd"] }
7272
mimalloc = { version = "0.1.25", default-features = false }
7373
snmalloc-rs = { version = "0.3.3", features = ["native-cpu"] }
7474
yarte = { version = "0.15", features = ["bytes-buf", "json"] }

frameworks/Rust/ntex/src/db.rs

Lines changed: 29 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
use std::cell::Cell;
2-
31
use nanorand::{Rng, WyRand};
4-
use ntex::util::{Bytes, BytesVec};
2+
use ntex::util::Bytes;
53
use smallvec::SmallVec;
64
use tokio_postgres::{connect, Client, Statement};
75
use yarte::TemplateBytesTrait;
@@ -29,11 +27,10 @@ pub struct FortunesTemplate<'a, 'b> {
2927
/// Postgres interface
3028
pub struct PgConnection {
3129
cl: Client,
30+
rng: WyRand,
3231
fortune: Statement,
3332
world: Statement,
34-
rng: WyRand,
3533
updates: Statement,
36-
buf: Cell<Option<BytesVec>>,
3734
}
3835

3936
impl PgConnection {
@@ -51,33 +48,30 @@ impl PgConnection {
5148

5249
PgConnection {
5350
cl,
54-
fortune,
5551
world,
5652
updates,
53+
fortune,
5754
rng: WyRand::new(),
58-
buf: Cell::new(Some(BytesVec::with_capacity(10 * 1024 * 1024))),
5955
}
6056
}
6157
}
6258

6359
impl PgConnection {
6460
pub async fn get_world(&self) -> Bytes {
6561
let random_id = (self.rng.clone().generate::<u32>() % 10_000 + 1) as i32;
66-
6762
let row = self.cl.query_one(&self.world, &[&random_id]).await.unwrap();
6863

69-
let mut body = self.buf.take().unwrap();
70-
sonic_rs::to_writer(
71-
utils::BVecWriter::new(&mut body),
72-
&World {
73-
id: row.get(0),
74-
randomnumber: row.get(1),
75-
},
76-
)
77-
.unwrap();
78-
let result = body.take_bytes();
79-
self.buf.set(Some(body));
80-
result
64+
utils::buffer(256, |body| {
65+
sonic_rs::to_writer(
66+
utils::BVecWriter(body),
67+
&World {
68+
id: row.get(0),
69+
randomnumber: row.get(1),
70+
},
71+
)
72+
.unwrap();
73+
body.take()
74+
})
8175
}
8276

8377
pub async fn get_worlds(&self, num: usize) -> Bytes {
@@ -97,11 +91,10 @@ impl PgConnection {
9791
})
9892
}
9993

100-
let mut body = self.buf.take().unwrap();
101-
sonic_rs::to_writer(utils::BVecWriter::new(&mut body), &worlds[..]).unwrap();
102-
let result = body.take_bytes();
103-
self.buf.set(Some(body));
104-
result
94+
utils::buffer(2 * 1024, |body| {
95+
sonic_rs::to_writer(utils::BVecWriter(body), &worlds[..]).unwrap();
96+
body.take()
97+
})
10598
}
10699

107100
pub async fn update(&self, num: usize) -> Bytes {
@@ -130,14 +123,12 @@ impl PgConnection {
130123
for query in queries {
131124
let _rand: i32 = query.await.unwrap().get(1);
132125
}
133-
134126
update.await.unwrap();
135127

136-
let mut body = self.buf.take().unwrap();
137-
sonic_rs::to_writer(utils::BVecWriter::new(&mut body), &worlds[..]).unwrap();
138-
let result = body.take_bytes();
139-
self.buf.set(Some(body));
140-
result
128+
utils::buffer(2 * 1024, |body| {
129+
sonic_rs::to_writer(utils::BVecWriter(body), &worlds[..]).unwrap();
130+
body.take()
131+
})
141132
}
142133

143134
pub async fn tell_fortune(&self) -> Bytes {
@@ -154,16 +145,13 @@ impl PgConnection {
154145
}));
155146
fortunes.sort_by(|it, next| it.message.cmp(&next.message));
156147

157-
let mut body = self.buf.take().unwrap();
158-
utils::reserve(&mut body, 4 * 1024);
159-
FortunesTemplate {
160-
fortunes: &fortunes,
161-
}
162-
.write_call(&mut body);
163-
fortunes.clear();
148+
utils::buffer(4 * 1024, |body| {
149+
FortunesTemplate {
150+
fortunes: &fortunes,
151+
}
152+
.write_call(body);
164153

165-
let result = body.take_bytes();
166-
self.buf.set(Some(body));
167-
result
154+
body.take()
155+
})
168156
}
169157
}

frameworks/Rust/ntex/src/main.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
33

44
use ntex::http::header::{CONTENT_TYPE, SERVER};
5-
use ntex::{http, util::BytesVec, web};
5+
use ntex::{http, web};
66
use sonic_rs::Serialize;
77

88
mod utils;
@@ -14,16 +14,19 @@ pub struct Message {
1414

1515
#[web::get("/json")]
1616
async fn json() -> web::HttpResponse {
17-
let mut body = BytesVec::with_capacity(utils::SIZE);
18-
sonic_rs::to_writer(
19-
utils::BVecWriter(&mut body),
20-
&Message {
21-
message: "Hello, World!",
22-
},
23-
)
24-
.unwrap();
25-
26-
let mut response = web::HttpResponse::with_body(http::StatusCode::OK, body.freeze().into());
17+
let body = utils::buffer(256, |buf| {
18+
sonic_rs::to_writer(
19+
utils::BVecWriter(buf),
20+
&Message {
21+
message: "Hello, World!",
22+
},
23+
)
24+
.unwrap();
25+
26+
buf.take()
27+
});
28+
29+
let mut response = web::HttpResponse::with_body(http::StatusCode::OK, body.into());
2730
response.headers_mut().insert(SERVER, utils::HDR_SERVER);
2831
response
2932
.headers_mut()

frameworks/Rust/ntex/src/main_plt.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ impl Future for App {
3535
match ready!(this.io.poll_recv(&this.codec, cx)) {
3636
Ok((req, _)) => {
3737
let _ = this.io.with_write_buf(|buf| {
38-
utils::reserve(buf, 2 * 1024);
38+
this.io.cfg().write_buf().resize(buf);
3939
match req.path() {
4040
"/json" => {
4141
buf.extend_from_slice(JSON);

frameworks/Rust/ntex/src/utils.rs

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
#![allow(dead_code)]
2-
use std::{cmp, io, io::Write, mem::MaybeUninit, slice::from_raw_parts_mut};
2+
use std::{cell::Cell, cmp, io, io::Write, mem::MaybeUninit, slice::from_raw_parts_mut};
33

44
use atoi::FromRadix10;
55
use ntex::http::{header::HeaderValue, HttpServiceConfig, KeepAlive};
6-
use ntex::util::{BufMut, Bytes, BytesVec};
6+
use ntex::util::{BufMut, Bytes, BytesMut};
77
use ntex::{io::IoConfig, time::Seconds, SharedCfg};
88
use sonic_rs::writer::WriteExt;
99

@@ -15,7 +15,7 @@ pub const HDR_HTML_CONTENT_TYPE: HeaderValue =
1515
pub const BODY_PLAIN_TEXT: Bytes = Bytes::from_static(b"Hello, World!");
1616

1717
const HW: usize = 128 * 1024;
18-
pub const SIZE: usize = 27;
18+
pub const SIZE: usize = 23;
1919

2020
pub fn config() -> SharedCfg {
2121
thread_local! {
@@ -58,22 +58,28 @@ pub fn get_query_param(query: Option<&str>) -> usize {
5858
cmp::min(500, cmp::max(1, q) as usize)
5959
}
6060

61-
pub fn reserve(buf: &mut BytesVec, lw: usize) {
62-
let remaining = buf.remaining_mut();
63-
if remaining < lw {
64-
buf.reserve(HW);
61+
pub fn buffer<F, R>(lw: usize, f: F) -> R
62+
where
63+
F: FnOnce(&mut BytesMut) -> R,
64+
{
65+
thread_local! {
66+
static BUF: Cell<Option<BytesMut>> = Cell::new(Some(BytesMut::new()));
6567
}
66-
}
67-
68-
pub struct BVecWriter<'a>(pub &'a mut BytesVec);
68+
BUF.with(|buf| {
69+
let mut b = buf.take().unwrap();
70+
let remaining = b.remaining_mut();
71+
if remaining < lw {
72+
b.reserve_capacity(HW);
73+
}
6974

70-
impl<'a> BVecWriter<'a> {
71-
pub fn new(buf: &'a mut BytesVec) -> BVecWriter<'a> {
72-
reserve(buf, 2048);
73-
Self(buf)
74-
}
75+
let result = f(&mut b);
76+
buf.set(Some(b));
77+
result
78+
})
7579
}
7680

81+
pub struct BVecWriter<'a>(pub &'a mut BytesMut);
82+
7783
impl Write for BVecWriter<'_> {
7884
fn write(&mut self, src: &[u8]) -> Result<usize, io::Error> {
7985
self.0.extend_from_slice(src);

0 commit comments

Comments
 (0)