Skip to content

Commit

Permalink
Use updated Service trait
Browse files Browse the repository at this point in the history
  • Loading branch information
fafhrd91 committed Dec 4, 2024
1 parent 15008af commit 681bb77
Show file tree
Hide file tree
Showing 11 changed files with 133 additions and 135 deletions.
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changes

## [4.5.0] - 2024-12-04

* Use updated Service trait

## [4.4.0] - 2024-11-10

* Check service readiness once per decoded item
Expand Down
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "ntex-mqtt"
version = "4.4.0"
version = "4.5.0"
authors = ["ntex contributors <[email protected]>"]
description = "Client and Server framework for MQTT v5 and v3.1.1 protocols"
documentation = "https://docs.rs/ntex-mqtt"
Expand All @@ -17,8 +17,8 @@ features = ["ntex/tokio"]
[dependencies]
ntex-io = "2"
ntex-net = "2"
ntex-util = "2.5"
ntex-service = "3.3.3"
ntex-util = "2.8"
ntex-service = "3.4"
ntex-bytes = "0.1"
ntex-codec = "0.6"
ntex-router = "0.5"
Expand Down
15 changes: 2 additions & 13 deletions src/inflight.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use std::{cell::Cell, future::poll_fn, rc::Rc, task::Context, task::Poll};

use ntex_service::{Middleware, Service, ServiceCtx};
use ntex_util::{future::join, future::select, task::LocalWaker};
use ntex_util::{future::join, task::LocalWaker};

/// Trait for types that could be sized
pub trait SizedRequest {
Expand Down Expand Up @@ -83,13 +83,6 @@ where
}
}

#[inline]
async fn not_ready(&self) {
if self.count.is_available() {
select(self.count.unavailable(), self.service.not_ready()).await;
}
}

#[inline]
async fn call(&self, req: R, ctx: ServiceCtx<'_, Self>) -> Result<S::Response, S::Error> {
let size = if self.count.0.max_size > 0 { req.size() } else { 0 };
Expand All @@ -99,6 +92,7 @@ where
result
}

ntex_service::forward_poll!(service);
ntex_service::forward_shutdown!(service);
}

Expand Down Expand Up @@ -135,10 +129,6 @@ impl Counter {
async fn available(&self) {
poll_fn(|cx| if self.0.available(cx) { Poll::Ready(()) } else { Poll::Pending }).await
}

async fn unavailable(&self) {
poll_fn(|cx| if self.0.available(cx) { Poll::Pending } else { Poll::Ready(()) }).await
}
}

struct CounterGuard(u32, Rc<CounterInner>);
Expand Down Expand Up @@ -305,7 +295,6 @@ mod tests {
}))
.bind();
assert_eq!(lazy(|cx| srv.poll_ready(cx)).await, Poll::Ready(Ok(())));
assert_eq!(lazy(|cx| srv.poll_not_ready(cx)).await, Poll::Pending);

let srv2 = srv.clone();
ntex_util::spawn(async move {
Expand Down
33 changes: 1 addition & 32 deletions src/io.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! Framed transport dispatcher
use std::future::{poll_fn, Future};
use std::task::{ready, Context, Poll};
use std::{cell::Cell, cell::RefCell, collections::VecDeque, pin::Pin, rc::Rc};
use std::{cell::Cell, cell::RefCell, collections::VecDeque, future::Future, pin::Pin, rc::Rc};

use ntex_codec::{Decoder, Encoder};
use ntex_io::{
Expand Down Expand Up @@ -255,12 +254,6 @@ where
}
}

// start ready task
if inner.flags.contains(Flags::READY_TASK) {
inner.flags.insert(Flags::READY_TASK);
ntex_rt::spawn(not_ready(inner.state.clone(), inner.service.clone()));
}

loop {
match inner.st {
IoDispatcherState::Processing => {
Expand Down Expand Up @@ -595,30 +588,6 @@ where
}
}

async fn not_ready<S, U>(
slf: Rc<DispatcherState<S, U>>,
pl: PipelineBinding<S, DispatchItem<U>>,
) where
S: Service<DispatchItem<U>, Response = Option<Response<U>>> + 'static,
U: Encoder + Decoder + 'static,
{
loop {
if !pl.is_shutdown() {
if let Err(err) = poll_fn(|cx| pl.poll_ready(cx)).await {
slf.error.set(Some(IoDispatcherError::Service(err)));
break;
}
if !pl.is_shutdown() {
poll_fn(|cx| pl.poll_not_ready(cx)).await;
slf.ready.set(false);
slf.waker.wake();
continue;
}
}
break;
}
}

#[cfg(test)]
mod tests {
use std::{cell::Cell, io, sync::Arc, sync::Mutex};
Expand Down
11 changes: 6 additions & 5 deletions src/server.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{fmt, io, marker};
use std::{fmt, io, marker, task::Context};

use ntex_codec::{Decoder, Encoder};
use ntex_io::{DispatchItem, Filter, Io, IoBoxed};
Expand Down Expand Up @@ -234,8 +234,9 @@ where
}

#[inline]
async fn not_ready(&self) {
select(self.handlers.0.not_ready(), self.handlers.1.not_ready()).await;
fn poll(&self, cx: &mut Context<'_>) -> Result<(), Self::Error> {
self.handlers.0.poll(cx)?;
self.handlers.1.poll(cx)
}

#[inline]
Expand Down Expand Up @@ -302,8 +303,8 @@ where
}

#[inline]
async fn not_ready(&self) {
Service::<IoBoxed>::not_ready(self).await
fn poll(&self, cx: &mut Context<'_>) -> Result<(), Self::Error> {
Service::<IoBoxed>::poll(self, cx)
}

#[inline]
Expand Down
36 changes: 24 additions & 12 deletions src/v3/client/dispatcher.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::{cell::RefCell, marker::PhantomData, num::NonZeroU16, rc::Rc};
use std::{cell::RefCell, marker::PhantomData, num::NonZeroU16, rc::Rc, task::Context};

use ntex_io::DispatchItem;
use ntex_service::{Pipeline, Service, ServiceCtx};
use ntex_util::future::{join, select, Either};
use ntex_util::future::{join, Either};
use ntex_util::{services::inflight::InFlightService, HashSet};

use crate::error::{HandshakeError, MqttError, ProtocolError};
Expand Down Expand Up @@ -38,7 +38,7 @@ pub(crate) struct Dispatcher<T, C: Service<Control<E>>, E> {
}

struct Inner<C> {
control: C,
control: Pipeline<C>,
sink: Rc<MqttShared>,
inflight: RefCell<HashSet<NonZeroU16>>,
}
Expand All @@ -51,15 +51,19 @@ where
pub(crate) fn new(sink: Rc<MqttShared>, publish: T, control: C) -> Self {
Self {
publish,
inner: Rc::new(Inner { sink, control, inflight: RefCell::new(HashSet::default()) }),
inner: Rc::new(Inner {
sink,
control: Pipeline::new(control),
inflight: RefCell::new(HashSet::default()),
}),
_t: PhantomData,
}
}
}

impl<T, C, E> Service<DispatchItem<Rc<MqttShared>>> for Dispatcher<T, C, E>
where
T: Service<Publish, Response = Either<(), Publish>, Error = E>,
T: Service<Publish, Response = Either<(), Publish>, Error = E> + 'static,
C: Service<Control<E>, Response = ControlAck, Error = MqttError<E>> + 'static,
E: 'static,
{
Expand All @@ -68,12 +72,13 @@ where

#[inline]
async fn ready(&self, ctx: ServiceCtx<'_, Self>) -> Result<(), Self::Error> {
let (res1, res2) = join(ctx.ready(&self.publish), ctx.ready(&self.inner.control)).await;
let (res1, res2) =
join(ctx.ready(&self.publish), ctx.ready(self.inner.control.get_ref())).await;
if let Err(e) = res1 {
if res2.is_err() {
Err(MqttError::Service(e))
} else {
match ctx.call_nowait(&self.inner.control, Control::error(e)).await {
match ctx.call_nowait(self.inner.control.get_ref(), Control::error(e)).await {
Ok(_) => {
self.inner.sink.close();
Ok(())
Expand All @@ -86,14 +91,21 @@ where
}
}

#[inline]
async fn not_ready(&self) {
select(self.publish.not_ready(), self.inner.control.not_ready()).await;
fn poll(&self, cx: &mut Context<'_>) -> Result<(), Self::Error> {
if let Err(e) = self.publish.poll(cx) {
let inner = self.inner.clone();
ntex_rt::spawn(async move {
if inner.control.call_nowait(Control::error(e.into())).await.is_ok() {

Check failure on line 98 in src/v3/client/dispatcher.rs

View workflow job for this annotation

GitHub Actions / clippy

useless conversion to the same type: `E`

error: useless conversion to the same type: `E` --> src/v3/client/dispatcher.rs:98:61 | 98 | if inner.control.call_nowait(Control::error(e.into())).await.is_ok() { | ^^^^^^^^ help: consider removing `.into()`: `e` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion note: the lint level is defined here --> src/lib.rs:1:27 | 1 | #![deny(rust_2018_idioms, warnings, unreachable_pub)] | ^^^^^^^^ = note: `#[deny(clippy::useless_conversion)]` implied by `#[deny(warnings)]`
inner.sink.close();
}
});
}
self.inner.control.poll(cx)
}

async fn shutdown(&self) {
self.inner.sink.close();
let _ = Pipeline::new(&self.inner.control).call(Control::closed()).await;
let _ = self.inner.control.call(Control::closed()).await;

self.publish.shutdown().await;
self.inner.control.shutdown().await
Expand Down Expand Up @@ -231,7 +243,7 @@ async fn control<'f, T, C, E>(
where
C: Service<Control<E>, Response = ControlAck, Error = MqttError<E>>,
{
let packet = match ctx.call(&inner.control, msg).await?.result {
let packet = match ctx.call(inner.control.get_ref(), msg).await?.result {
ControlAckKind::Ping => Some(codec::Packet::PingResponse),
ControlAckKind::PublishAck(id) => {
inner.inflight.borrow_mut().remove(&id);
Expand Down
39 changes: 27 additions & 12 deletions src/v3/dispatcher.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use std::{cell::RefCell, marker::PhantomData, num::NonZeroU16, rc::Rc};
use std::{cell::RefCell, marker::PhantomData, num::NonZeroU16, rc::Rc, task::Context};

use ntex_io::DispatchItem;
use ntex_service::{Pipeline, Service, ServiceCtx, ServiceFactory};
use ntex_util::services::buffer::{BufferService, BufferServiceError};
use ntex_util::services::inflight::InFlightService;
use ntex_util::{future::join, future::select, HashSet};
use ntex_util::{future::join, HashSet};

use crate::error::{HandshakeError, MqttError, ProtocolError};
use crate::types::QoS;
Expand Down Expand Up @@ -88,7 +88,7 @@ pub(crate) struct Dispatcher<T, C: Service<Control<E>>, E> {
}

struct Inner<C> {
control: C,
control: Pipeline<C>,
sink: Rc<MqttShared>,
inflight: RefCell<HashSet<NonZeroU16>>,
}
Expand All @@ -110,7 +110,11 @@ where
publish,
max_qos,
handle_qos_after_disconnect,
inner: Rc::new(Inner { sink, control, inflight: RefCell::new(HashSet::default()) }),
inner: Rc::new(Inner {
sink,
control: Pipeline::new(control),
inflight: RefCell::new(HashSet::default()),
}),
_t: PhantomData,
}
}
Expand All @@ -119,20 +123,24 @@ where
impl<T, C, E> Service<DispatchItem<Rc<MqttShared>>> for Dispatcher<T, C, E>
where
E: From<T::Error> + 'static,
T: Service<Publish, Response = ()>,
T: Service<Publish, Response = ()> + 'static,
C: Service<Control<E>, Response = ControlAck, Error = MqttError<E>> + 'static,
{
type Response = Option<codec::Packet>;
type Error = MqttError<E>;

#[inline]
async fn ready(&self, ctx: ServiceCtx<'_, Self>) -> Result<(), Self::Error> {
let (res1, res2) = join(ctx.ready(&self.publish), ctx.ready(&self.inner.control)).await;
let (res1, res2) =
join(ctx.ready(&self.publish), ctx.ready(self.inner.control.get_ref())).await;
if let Err(e) = res1 {
if res2.is_err() {
Err(MqttError::Service(e.into()))
} else {
match ctx.call_nowait(&self.inner.control, Control::error(e.into())).await {
match ctx
.call_nowait(self.inner.control.get_ref(), Control::error(e.into()))
.await
{
Ok(_) => {
self.inner.sink.close();
Ok(())
Expand All @@ -145,14 +153,21 @@ where
}
}

#[inline]
async fn not_ready(&self) {
select(self.publish.not_ready(), self.inner.control.not_ready()).await;
fn poll(&self, cx: &mut Context<'_>) -> Result<(), Self::Error> {
if let Err(e) = self.publish.poll(cx) {
let inner = self.inner.clone();
ntex_rt::spawn(async move {
if inner.control.call_nowait(Control::error(e.into())).await.is_ok() {
inner.sink.close();
}
});
}
self.inner.control.poll(cx)
}

async fn shutdown(&self) {
self.inner.sink.close();
let _ = Pipeline::new(&self.inner.control).call(Control::closed()).await;
let _ = self.inner.control.call(Control::closed()).await;

self.publish.shutdown().await;
self.inner.control.shutdown().await;
Expand Down Expand Up @@ -387,7 +402,7 @@ where
let mut error = matches!(pkt, Control::Error(_) | Control::ProtocolError(_));

loop {
match ctx.call(&inner.control, pkt).await {
match ctx.call(inner.control.get_ref(), pkt).await {
Ok(item) => {
let packet = match item.result {
ControlAckKind::Ping => Some(codec::Packet::PingResponse),
Expand Down
20 changes: 5 additions & 15 deletions src/v3/router.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{future::poll_fn, future::Future, pin::Pin, rc::Rc, task::Poll};
use std::{rc::Rc, task::Context};

use ntex_router::{IntoPattern, RouterBuilder};
use ntex_service::boxed::{self, BoxService, BoxServiceFactory};
Expand Down Expand Up @@ -117,24 +117,14 @@ impl<Err> Service<Publish> for RouterService<Err> {
}

#[inline]
async fn not_ready(&self) {
let mut futs = Vec::with_capacity(self.handlers.len() + 1);
fn poll(&self, cx: &mut Context<'_>) -> Result<(), Self::Error> {
for hnd in &self.handlers {
futs.push(Box::pin(hnd.not_ready()));
hnd.poll(cx)?;
}
futs.push(Box::pin(self.default.not_ready()));

poll_fn(|cx| {
for hnd in &mut futs {
if Pin::new(hnd).poll(cx).is_ready() {
return Poll::Ready(());
}
}
Poll::Pending
})
.await;
self.default.poll(cx)
}

#[inline]
async fn call(
&self,
mut req: Publish,
Expand Down
Loading

0 comments on commit 681bb77

Please sign in to comment.