2828#include < cstdint>
2929#include < future>
3030#include < optional>
31+
3132#ifdef USE_ASIO
3233#include < asio/bind_executor.hpp>
3334#include < asio/io_context.hpp>
5253
5354#include " AsioTimer.h"
5455#include " Commands.h"
56+ #include " ExecutorService.h"
5557#include " GetLastMessageIdResponse.h"
5658#include " LookupDataResult.h"
59+ #include " PendingRequest.h"
5760#include " SharedBuffer.h"
5861#include " TimeUtils.h"
5962#include " UtilAllocator.h"
@@ -66,9 +69,6 @@ class PulsarFriend;
6669
6770using TcpResolverPtr = std::shared_ptr<ASIO::ip::tcp::resolver>;
6871
69- class ExecutorService ;
70- using ExecutorServicePtr = std::shared_ptr<ExecutorService>;
71-
7272class ConnectionPool ;
7373class ClientConnection ;
7474typedef std::shared_ptr<ClientConnection> ClientConnectionPtr;
@@ -225,47 +225,6 @@ class PULSAR_PUBLIC ClientConnection : public std::enable_shared_from_this<Clien
225225 void handleKeepAliveTimeout (const ASIO_ERROR& ec);
226226
227227 private:
228- struct PendingRequestData {
229- Promise<Result, ResponseData> promise;
230- DeadlineTimerPtr timer;
231- std::shared_ptr<std::atomic_bool> hasGotResponse{std::make_shared<std::atomic_bool>(false )};
232-
233- void fail (Result result) {
234- cancelTimer (*timer);
235- promise.setFailed (result);
236- }
237- };
238-
239- struct LookupRequestData {
240- LookupDataResultPromisePtr promise;
241- DeadlineTimerPtr timer;
242-
243- void fail (Result result) {
244- cancelTimer (*timer);
245- promise->setFailed (result);
246- }
247- };
248-
249- struct LastMessageIdRequestData {
250- GetLastMessageIdResponsePromisePtr promise;
251- DeadlineTimerPtr timer;
252-
253- void fail (Result result) {
254- cancelTimer (*timer);
255- promise->setFailed (result);
256- }
257- };
258-
259- struct GetSchemaRequest {
260- Promise<Result, SchemaInfo> promise;
261- DeadlineTimerPtr timer;
262-
263- void fail (Result result) {
264- cancelTimer (*timer);
265- promise.setFailed (result);
266- }
267- };
268-
269228 /*
270229 * handler for connectAsync
271230 * creates a ConnectionPtr which has a valid ClientConnection object
@@ -303,12 +262,6 @@ class PULSAR_PUBLIC ClientConnection : public std::enable_shared_from_this<Clien
303262 void newLookup (const SharedBuffer& cmd, uint64_t requestId, const char * requestType,
304263 const LookupDataResultPromisePtr& promise);
305264
306- void handleRequestTimeout (const ASIO_ERROR& ec, const PendingRequestData& pendingRequestData);
307-
308- void handleLookupTimeout (const ASIO_ERROR&, const LookupRequestData&);
309-
310- void handleGetLastMessageIdTimeout (const ASIO_ERROR&, const LastMessageIdRequestData& data);
311-
312265 template <typename Handler>
313266 inline AllocHandler<Handler> customAllocReadHandler (Handler h) {
314267 return AllocHandler<Handler>(readHandlerAllocator_, h);
@@ -385,33 +338,49 @@ class PULSAR_PUBLIC ClientConnection : public std::enable_shared_from_this<Clien
385338 const std::chrono::milliseconds connectTimeout_;
386339 const DeadlineTimerPtr connectTimer_;
387340
388- typedef std::map< long , PendingRequestData> PendingRequestsMap;
389- PendingRequestsMap pendingRequests_ ;
341+ template < typename T>
342+ using RequestMap = std::unordered_map< uint64_t , PendingRequestPtr<T>> ;
390343
391- typedef std::map<long , LookupRequestData> PendingLookupRequestsMap;
392- PendingLookupRequestsMap pendingLookupRequests_;
344+ RequestMap<ResponseData> pendingRequests_;
345+ RequestMap<LookupDataResultPtr> pendingLookupRequests_;
346+ RequestMap<GetLastMessageIdResponse> pendingGetLastMessageIdRequests_;
347+ RequestMap<NamespaceTopicsPtr> pendingGetNamespaceTopicsRequests_;
348+ RequestMap<SchemaInfo> pendingGetSchemaRequests_;
393349
394- typedef std::map <long , ProducerImplWeakPtr> ProducersMap;
350+ typedef std::unordered_map <long , ProducerImplWeakPtr> ProducersMap;
395351 ProducersMap producers_;
396352
397- typedef std::map <long , ConsumerImplWeakPtr> ConsumersMap;
353+ typedef std::unordered_map <long , ConsumerImplWeakPtr> ConsumersMap;
398354 ConsumersMap consumers_;
399355
400356 typedef std::map<uint64_t , Promise<Result, BrokerConsumerStatsImpl>> PendingConsumerStatsMap;
401357 PendingConsumerStatsMap pendingConsumerStatsMap_;
402358
403- typedef std::map<long , LastMessageIdRequestData> PendingGetLastMessageIdRequestsMap;
404- PendingGetLastMessageIdRequestsMap pendingGetLastMessageIdRequests_;
405-
406- typedef std::map<long , Promise<Result, NamespaceTopicsPtr>> PendingGetNamespaceTopicsMap;
407- PendingGetNamespaceTopicsMap pendingGetNamespaceTopicsRequests_;
408-
409- typedef std::unordered_map<uint64_t , GetSchemaRequest> PendingGetSchemaMap;
410- PendingGetSchemaMap pendingGetSchemaRequests_;
411-
412359 mutable std::mutex mutex_;
413360 typedef std::unique_lock<std::mutex> Lock;
414361
362+ // Note: this method must be called when holding `mutex_`
363+ template <typename T, typename OnTimeout>
364+ auto insertRequest (RequestMap<T>& pendingRequests, uint64_t requestId, OnTimeout onTimeout) {
365+ auto request = std::make_shared<PendingRequest<T>>(
366+ executor_->createTimer (operationsTimeout_),
367+ [this , self{shared_from_this ()}, requestId, onTimeout{std::move (onTimeout)},
368+ &pendingRequests]() mutable {
369+ {
370+ std::lock_guard lock{mutex_};
371+ if (auto it = pendingRequests.find (requestId); it != pendingRequests.end ()) {
372+ pendingRequests.erase (it);
373+ }
374+ }
375+ onTimeout ();
376+ });
377+ auto [iterator, inserted] = pendingRequests.emplace (requestId, request);
378+ if (inserted) {
379+ request->initialize ();
380+ } // else: the request id is duplicated
381+ return iterator->second ;
382+ }
383+
415384 // Pending buffers to write on the socket
416385 std::deque<std::any> pendingWriteBuffers_;
417386 int pendingWriteOperations_ = 0 ;
@@ -435,7 +404,7 @@ class PULSAR_PUBLIC ClientConnection : public std::enable_shared_from_this<Clien
435404
436405 void startConsumerStatsTimer (std::vector<uint64_t > consumerStatsRequests);
437406 uint32_t maxPendingLookupRequest_;
438- uint32_t numOfPendingLookupRequest_ = 0 ;
407+ std:: atomic_uint32_t numOfPendingLookupRequest_{ 0 } ;
439408
440409 bool isTlsAllowInsecureConnection_ = false ;
441410
0 commit comments