22//! async eventloop.
33use std:: time:: Duration ;
44
5+ use super :: eventloop:: ChannelCapacity ;
56use super :: mqttbytes:: v5:: {
67 Filter , PubAck , PubRec , Publish , PublishProperties , Subscribe , SubscribeProperties ,
78 Unsubscribe , UnsubscribeProperties ,
@@ -37,6 +38,62 @@ impl From<TrySendError<Request>> for ClientError {
3738 }
3839}
3940
41+ /// Builder for synchronous and asynchronous MQTT v5 clients.
42+ ///
43+ /// The request channel is bounded by default, using the capacity configured
44+ /// in [`MqttOptions`]. Call [`capacity`](Self::capacity) to override it or
45+ /// [`unbounded`](Self::unbounded) to opt out of backpressure entirely.
46+ pub struct AsyncClientBuilder {
47+ options : MqttOptions ,
48+ capacity : ChannelCapacity ,
49+ }
50+
51+ impl AsyncClientBuilder {
52+ /// Create a new builder. The channel capacity defaults to the value set
53+ /// in [`MqttOptions::request_channel_capacity`].
54+ pub fn new ( options : MqttOptions ) -> Self {
55+ let capacity = ChannelCapacity :: Bounded ( options. request_channel_capacity ( ) ) ;
56+ Self { options, capacity }
57+ }
58+
59+ /// Set a bounded request channel with the given capacity.
60+ /// A capacity of `0` creates a rendezvous channel.
61+ pub fn capacity ( mut self , cap : usize ) -> Self {
62+ self . capacity = ChannelCapacity :: Bounded ( cap) ;
63+ self
64+ }
65+
66+ /// Use an unbounded request channel.
67+ /// This removes backpressure from the client. Prefer bounded channels
68+ /// unless you have a specific reason to allow unbounded queuing.
69+ pub fn unbounded ( mut self ) -> Self {
70+ self . capacity = ChannelCapacity :: Unbounded ;
71+ self
72+ }
73+
74+ /// Build an [`AsyncClient`] and its [`EventLoop`].
75+ pub fn build_async ( self ) -> ( AsyncClient , EventLoop ) {
76+ let eventloop = EventLoop :: new ( self . options , self . capacity ) ;
77+ let request_tx = eventloop. requests_tx . clone ( ) ;
78+ let client = AsyncClient :: from_senders ( request_tx) ;
79+ ( client, eventloop)
80+ }
81+
82+ /// Build a [`Client`] and its [`Connection`].
83+ pub fn build ( self ) -> ( Client , Connection ) {
84+ let ( async_client, eventloop) = self . build_async ( ) ;
85+ let client = Client {
86+ client : async_client,
87+ } ;
88+ let runtime = runtime:: Builder :: new_current_thread ( )
89+ . enable_all ( )
90+ . build ( )
91+ . unwrap ( ) ;
92+ let connection = Connection :: new ( eventloop, runtime) ;
93+ ( client, connection)
94+ }
95+ }
96+
4097/// An asynchronous client, communicates with MQTT `EventLoop`.
4198///
4299/// This is cloneable and can be used to asynchronously [`publish`](`AsyncClient::publish`),
@@ -50,16 +107,15 @@ pub struct AsyncClient {
50107}
51108
52109impl AsyncClient {
53- /// Create a new `AsyncClient`.
54- ///
55- /// `cap` specifies the capacity of the bounded async channel.
110+ /// Deprecated. Use [`AsyncClient::builder`] instead.
111+ #[ deprecated( since = "0.26.0" , note = "Use AsyncClient::builder instead" ) ]
56112 pub fn new ( options : MqttOptions , cap : usize ) -> ( AsyncClient , EventLoop ) {
57- let eventloop = EventLoop :: new ( options, cap) ;
58- let request_tx = eventloop. requests_tx . clone ( ) ;
59-
60- let client = AsyncClient { request_tx } ;
113+ AsyncClientBuilder :: new ( options) . capacity ( cap) . build_async ( )
114+ }
61115
62- ( client, eventloop)
116+ /// Returns an [`AsyncClientBuilder`] for constructing an MQTT v5 async client.
117+ pub fn builder ( options : MqttOptions ) -> AsyncClientBuilder {
118+ AsyncClientBuilder :: new ( options)
63119 }
64120
65121 /// Create a new `AsyncClient` from a channel `Sender`.
@@ -469,20 +525,15 @@ pub struct Client {
469525}
470526
471527impl Client {
472- /// Create a new `Client`
473- ///
474- /// `cap` specifies the capacity of the bounded async channel.
528+ /// Deprecated. Use [`Client::builder`] instead.
529+ #[ deprecated( since = "0.26.0" , note = "Use Client::builder instead" ) ]
475530 pub fn new ( options : MqttOptions , cap : usize ) -> ( Client , Connection ) {
476- let ( client, eventloop) = AsyncClient :: new ( options, cap) ;
477- let client = Client { client } ;
478-
479- let runtime = runtime:: Builder :: new_current_thread ( )
480- . enable_all ( )
481- . build ( )
482- . unwrap ( ) ;
531+ AsyncClientBuilder :: new ( options) . capacity ( cap) . build ( )
532+ }
483533
484- let connection = Connection :: new ( eventloop, runtime) ;
485- ( client, connection)
534+ /// Returns an [`AsyncClientBuilder`] for constructing an MQTT v5 sync client.
535+ pub fn builder ( options : MqttOptions ) -> AsyncClientBuilder {
536+ AsyncClientBuilder :: new ( options)
486537 }
487538
488539 /// Create a new `Client` from a channel `Sender`.
@@ -882,7 +933,7 @@ mod test {
882933 . set_keep_alive ( Duration :: from_secs ( 5 ) )
883934 . set_last_will ( will) ;
884935
885- let ( _, mut connection) = Client :: new ( mqttoptions, 10 ) ;
936+ let ( _, mut connection) = Client :: builder ( mqttoptions) . capacity ( 10 ) . build ( ) ;
886937 let _ = connection. iter ( ) ;
887938 let _ = connection. iter ( ) ;
888939 }
0 commit comments