2525#include < any>
2626#include < atomic>
2727#include < cstdint>
28+ #include < future>
29+ #include < optional>
2830#ifdef USE_ASIO
2931#include < asio/bind_executor.hpp>
3032#include < asio/io_context.hpp>
4143#include < deque>
4244#include < functional>
4345#include < memory>
46+ #include < mutex>
4447#include < string>
4548#include < unordered_map>
49+ #include < utility>
4650#include < vector>
4751
4852#include " AsioTimer.h"
@@ -156,11 +160,8 @@ class PULSAR_PUBLIC ClientConnection : public std::enable_shared_from_this<Clien
156160 * Close the connection.
157161 *
158162 * @param result all pending futures will complete with this result
159- * @param detach remove it from the pool if it's true
160- *
161- * `detach` should only be false when the connection pool is closed.
162163 */
163- void close (Result result = ResultConnectError, bool detach = true );
164+ const std::future< void >& close (Result result = ResultConnectError);
164165
165166 bool isClosed () const ;
166167
@@ -193,7 +194,7 @@ class PULSAR_PUBLIC ClientConnection : public std::enable_shared_from_this<Clien
193194
194195 const std::string& brokerAddress () const ;
195196
196- const std::string& cnxString () const ;
197+ auto cnxString () const { return * std::atomic_load (&cnxStringPtr_); }
197198
198199 int getServerProtocolVersion () const ;
199200
@@ -219,28 +220,48 @@ class PULSAR_PUBLIC ClientConnection : public std::enable_shared_from_this<Clien
219220 mockingRequests_.store (true , std::memory_order_release);
220221 }
221222
222- void handleKeepAliveTimeout ();
223+ void handleKeepAliveTimeout (const ASIO_ERROR& ec );
223224
224225 private:
225226 struct PendingRequestData {
226227 Promise<Result, ResponseData> promise;
227228 DeadlineTimerPtr timer;
228229 std::shared_ptr<std::atomic_bool> hasGotResponse{std::make_shared<std::atomic_bool>(false )};
230+
231+ void fail (Result result) {
232+ cancelTimer (*timer);
233+ promise.setFailed (result);
234+ }
229235 };
230236
231237 struct LookupRequestData {
232238 LookupDataResultPromisePtr promise;
233239 DeadlineTimerPtr timer;
240+
241+ void fail (Result result) {
242+ cancelTimer (*timer);
243+ promise->setFailed (result);
244+ }
234245 };
235246
236247 struct LastMessageIdRequestData {
237248 GetLastMessageIdResponsePromisePtr promise;
238249 DeadlineTimerPtr timer;
250+
251+ void fail (Result result) {
252+ cancelTimer (*timer);
253+ promise->setFailed (result);
254+ }
239255 };
240256
241257 struct GetSchemaRequest {
242258 Promise<Result, SchemaInfo> promise;
243259 DeadlineTimerPtr timer;
260+
261+ void fail (Result result) {
262+ cancelTimer (*timer);
263+ promise.setFailed (result);
264+ }
244265 };
245266
246267 /*
@@ -297,26 +318,26 @@ class PULSAR_PUBLIC ClientConnection : public std::enable_shared_from_this<Clien
297318 }
298319
299320 template <typename ConstBufferSequence, typename WriteHandler>
300- inline void asyncWrite (const ConstBufferSequence& buffers, WriteHandler handler) {
321+ inline void asyncWrite (const ConstBufferSequence& buffers, WriteHandler&& handler) {
301322 if (isClosed ()) {
302323 return ;
303324 }
304325 if (tlsSocket_) {
305- ASIO::async_write (*tlsSocket_, buffers, ASIO::bind_executor (strand_, handler));
326+ ASIO::async_write (*tlsSocket_, buffers, std::forward<WriteHandler>( handler));
306327 } else {
307- ASIO::async_write (*socket_, buffers, handler);
328+ ASIO::async_write (*socket_, buffers, std::forward<WriteHandler>( handler) );
308329 }
309330 }
310331
311332 template <typename MutableBufferSequence, typename ReadHandler>
312- inline void asyncReceive (const MutableBufferSequence& buffers, ReadHandler handler) {
333+ inline void asyncReceive (const MutableBufferSequence& buffers, ReadHandler&& handler) {
313334 if (isClosed ()) {
314335 return ;
315336 }
316337 if (tlsSocket_) {
317- tlsSocket_->async_read_some (buffers, ASIO::bind_executor (strand_, handler));
338+ tlsSocket_->async_read_some (buffers, std::forward<ReadHandler>( handler));
318339 } else {
319- socket_->async_receive (buffers, handler);
340+ socket_->async_receive (buffers, std::forward<ReadHandler>( handler) );
320341 }
321342 }
322343
@@ -337,7 +358,6 @@ class PULSAR_PUBLIC ClientConnection : public std::enable_shared_from_this<Clien
337358 */
338359 SocketPtr socket_;
339360 TlsSocketPtr tlsSocket_;
340- ASIO::strand<ASIO::io_context::executor_type> strand_;
341361
342362 const std::string logicalAddress_;
343363 /*
@@ -350,7 +370,7 @@ class PULSAR_PUBLIC ClientConnection : public std::enable_shared_from_this<Clien
350370 ClientConfiguration::ProxyProtocol proxyProtocol_;
351371
352372 // Represent both endpoint of the tcp connection. eg: [client:1234 -> server:6650]
353- std::string cnxString_ ;
373+ std::shared_ptr<std:: string> cnxStringPtr_ ;
354374
355375 /*
356376 * indicates if async connection establishment failed
@@ -360,7 +380,8 @@ class PULSAR_PUBLIC ClientConnection : public std::enable_shared_from_this<Clien
360380 SharedBuffer incomingBuffer_;
361381
362382 Promise<Result, ClientConnectionWeakPtr> connectPromise_;
363- std::shared_ptr<PeriodicTask> connectTimeoutTask_;
383+ const std::chrono::milliseconds connectTimeout_;
384+ const DeadlineTimerPtr connectTimer_;
364385
365386 typedef std::map<long , PendingRequestData> PendingRequestsMap;
366387 PendingRequestsMap pendingRequests_;
@@ -419,6 +440,7 @@ class PULSAR_PUBLIC ClientConnection : public std::enable_shared_from_this<Clien
419440 const std::string clientVersion_;
420441 ConnectionPool& pool_;
421442 const size_t poolIndex_;
443+ std::optional<std::future<void >> closeFuture_;
422444
423445 friend class PulsarFriend ;
424446 friend class ConsumerTest ;
0 commit comments