Introduce Sealed type instead of Box<dyn Filter>

This commit is contained in:
Nikolay Kim 2021-12-23 15:51:35 +06:00
parent 85a9485bac
commit 329ad46377
8 changed files with 50 additions and 21 deletions

View file

@ -1,5 +1,9 @@
# Changes # Changes
## [0.1.0-b.4] - 2021-12-23
* Introduce `Sealed` type instead of `Box<dyn Filter>`
## [0.1.0-b.3] - 2021-12-22 ## [0.1.0-b.3] - 2021-12-22
* Add .poll_write_backpressure() * Add .poll_write_backpressure()

View file

@ -1,6 +1,6 @@
[package] [package]
name = "ntex-io" name = "ntex-io"
version = "0.1.0-b.3" version = "0.1.0-b.4"
authors = ["ntex contributors <team@ntex.rs>"] authors = ["ntex contributors <team@ntex.rs>"]
description = "Utilities for encoding and decoding frames" description = "Utilities for encoding and decoding frames"
keywords = ["network", "framework", "async", "futures"] keywords = ["network", "framework", "async", "futures"]
@ -37,7 +37,7 @@ pin-project-lite = "0.2"
tok-io = { version = "1", package = "tokio", default-features = false, optional = true } tok-io = { version = "1", package = "tokio", default-features = false, optional = true }
[dev-dependencies] [dev-dependencies]
ntex = "0.5.0-b.0" ntex = "0.5.0-b.2"
futures = "0.3" futures = "0.3"
rand = "0.8" rand = "0.8"
env_logger = "0.9" env_logger = "0.9"

View file

@ -551,7 +551,7 @@ mod tests {
ready_err: Cell::new(false), ready_err: Cell::new(false),
st: Cell::new(DispatcherState::Processing), st: Cell::new(DispatcherState::Processing),
pool: state.memory_pool().pool(), pool: state.memory_pool().pool(),
io: state.into_boxed(), io: state.seal(),
shared, shared,
timer, timer,
ka_timeout, ka_timeout,

View file

@ -5,6 +5,8 @@ use ntex_bytes::BytesMut;
use super::io::Flags; use super::io::Flags;
use super::{Filter, IoRef, ReadStatus, WriteStatus}; use super::{Filter, IoRef, ReadStatus, WriteStatus};
pub struct Sealed(pub(crate) Box<dyn Filter>);
pub struct Base(IoRef); pub struct Base(IoRef);
impl Base { impl Base {

View file

@ -6,7 +6,7 @@ use ntex_bytes::{BytesMut, PoolId, PoolRef};
use ntex_codec::{Decoder, Encoder}; use ntex_codec::{Decoder, Encoder};
use ntex_util::{future::poll_fn, future::Either, task::LocalWaker, time::Millis}; use ntex_util::{future::poll_fn, future::Either, task::LocalWaker, time::Millis};
use super::filter::{Base, NullFilter}; use super::filter::{Base, NullFilter, Sealed};
use super::tasks::{ReadContext, WriteContext}; use super::tasks::{ReadContext, WriteContext};
use super::{Filter, FilterFactory, Handle, IoStream}; use super::{Filter, FilterFactory, Handle, IoStream};
@ -45,7 +45,7 @@ bitflags::bitflags! {
} }
enum FilterItem<F> { enum FilterItem<F> {
Boxed(Box<dyn Filter>), Boxed(Sealed),
Ptr(*mut F), Ptr(*mut F),
} }
@ -344,21 +344,26 @@ impl<F: Filter> Io<F> {
panic!() panic!()
} }
#[deprecated]
#[inline] #[inline]
pub fn into_boxed(mut self) -> crate::IoBoxed /// Convert current io stream into sealed version
where pub fn into_boxed(self) -> crate::IoBoxed {
F: 'static, self.seal()
{ }
#[inline]
/// Convert current io stream into sealed version
pub fn seal(mut self) -> crate::IoBoxed {
// get current filter // get current filter
let filter = unsafe { let filter = unsafe {
let item = mem::replace(&mut self.1, FilterItem::Ptr(std::ptr::null_mut())); let item = mem::replace(&mut self.1, FilterItem::Ptr(ptr::null_mut()));
let filter: Box<dyn Filter> = match item { let filter: Sealed = match item {
FilterItem::Boxed(b) => b, FilterItem::Boxed(b) => b,
FilterItem::Ptr(p) => Box::new(*Box::from_raw(p)), FilterItem::Ptr(p) => Sealed(Box::new(*Box::from_raw(p))),
}; };
let filter_ref: &'static dyn Filter = { let filter_ref: &'static dyn Filter = {
let filter: &dyn Filter = filter.as_ref(); let filter: &dyn Filter = filter.0.as_ref();
std::mem::transmute(filter) std::mem::transmute(filter)
}; };
self.0 .0.filter.replace(filter_ref); self.0 .0.filter.replace(filter_ref);
@ -384,7 +389,7 @@ impl<F: Filter> Io<F> {
{ {
// replace current filter // replace current filter
let filter = unsafe { let filter = unsafe {
let item = mem::replace(&mut self.1, FilterItem::Ptr(std::ptr::null_mut())); let item = mem::replace(&mut self.1, FilterItem::Ptr(ptr::null_mut()));
let filter = match item { let filter = match item {
FilterItem::Boxed(_) => panic!(), FilterItem::Boxed(_) => panic!(),
FilterItem::Ptr(p) => { FilterItem::Ptr(p) => {
@ -643,7 +648,7 @@ impl<F> Drop for Io<F> {
self.force_close(); self.force_close();
self.0 .0.filter.set(NullFilter::get()); self.0 .0.filter.set(NullFilter::get());
let _ = mem::replace(&mut self.1, FilterItem::Ptr(std::ptr::null_mut())); let _ = mem::replace(&mut self.1, FilterItem::Ptr(ptr::null_mut()));
unsafe { Box::from_raw(p) }; unsafe { Box::from_raw(p) };
} else { } else {
log::trace!( log::trace!(

View file

@ -516,7 +516,7 @@ mod tests {
.add_filter(CounterFactory(in_bytes.clone(), out_bytes.clone())) .add_filter(CounterFactory(in_bytes.clone(), out_bytes.clone()))
.await .await
.unwrap(); .unwrap();
let state = state.into_boxed(); let state = state.seal();
client.remote_buffer_cap(1024); client.remote_buffer_cap(1024);
client.write(TEXT); client.write(TEXT);

View file

@ -24,14 +24,14 @@ use ntex_codec::{Decoder, Encoder};
use ntex_util::time::Millis; use ntex_util::time::Millis;
pub use self::dispatcher::Dispatcher; pub use self::dispatcher::Dispatcher;
pub use self::filter::Base; pub use self::filter::{Base, Sealed};
pub use self::io::{Io, IoRef, OnDisconnect}; pub use self::io::{Io, IoRef, OnDisconnect};
pub use self::tasks::{ReadContext, WriteContext}; pub use self::tasks::{ReadContext, WriteContext};
pub use self::time::Timer; pub use self::time::Timer;
pub use self::utils::{filter_factory, into_boxed}; pub use self::utils::{filter_factory, seal};
pub type IoBoxed = Io<Box<dyn Filter>>; pub type IoBoxed = Io<Sealed>;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub enum ReadStatus { pub enum ReadStatus {
@ -146,6 +146,24 @@ pub mod rt {
pub use crate::tokio_rt::*; pub use crate::tokio_rt::*;
} }
#[deprecated]
#[doc(hidden)]
pub fn into_boxed<F, S>(
srv: S,
) -> impl ntex_service::ServiceFactory<
Config = S::Config,
Request = Io<F>,
Response = S::Response,
Error = S::Error,
InitError = S::InitError,
>
where
F: Filter + 'static,
S: ntex_service::ServiceFactory<Request = IoBoxed>,
{
seal(srv)
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View file

@ -6,7 +6,7 @@ use ntex_util::future::Ready;
use super::{Filter, FilterFactory, Io, IoBoxed}; use super::{Filter, FilterFactory, Io, IoBoxed};
/// Service that converts any Io<F> stream to IoBoxed stream /// Service that converts any Io<F> stream to IoBoxed stream
pub fn into_boxed<F, S>( pub fn seal<F, S>(
srv: S, srv: S,
) -> impl ServiceFactory< ) -> impl ServiceFactory<
Config = S::Config, Config = S::Config,
@ -23,7 +23,7 @@ where
let fut = srv.new_service(cfg); let fut = srv.new_service(cfg);
async move { async move {
let srv = fut.await?; let srv = fut.await?;
Ok(into_service(move |io: Io<F>| srv.call(io.into_boxed()))) Ok(into_service(move |io: Io<F>| srv.call(io.seal())))
} }
}) })
} }