@@ -135,10 +135,14 @@ void ProducerImpl::beforeConnectionChange(ClientConnection& connection) {
135135 connection.removeProducer (producerId_);
136136}
137137
138- void ProducerImpl::connectionOpened (const ClientConnectionPtr& cnx) {
138+ Future<Result, bool > ProducerImpl::connectionOpened (const ClientConnectionPtr& cnx) {
139+ // Do not use bool, only Result.
140+ Promise<Result, bool > promise;
141+
139142 if (state_ == Closed) {
140143 LOG_DEBUG (getName () << " connectionOpened : Producer is already closed" );
141- return ;
144+ promise.setFailed (ResultAlreadyClosed);
145+ return promise.getFuture ();
142146 }
143147
144148 ClientImplPtr client = client_.lock ();
@@ -149,9 +153,20 @@ void ProducerImpl::connectionOpened(const ClientConnectionPtr& cnx) {
149153 userProvidedProducerName_, conf_.isEncryptionEnabled (),
150154 static_cast <proto::ProducerAccessMode>(conf_.getAccessMode ()),
151155 topicEpoch, conf_.impl_ ->initialSubscriptionName );
156+
157+ // Keep a reference to ensure object is kept alive.
158+ auto self = shared_from_this ();
152159 cnx->sendRequestWithId (cmd, requestId)
153- .addListener (std::bind (&ProducerImpl::handleCreateProducer, shared_from_this (), cnx,
154- std::placeholders::_1, std::placeholders::_2));
160+ .addListener ([this , self, cnx, promise](Result result, const ResponseData& responseData) {
161+ Result handleResult = handleCreateProducer (cnx, result, responseData);
162+ if (handleResult == ResultOk) {
163+ promise.setSuccess ();
164+ } else {
165+ promise.setFailed (handleResult);
166+ }
167+ });
168+
169+ return promise.getFuture ();
155170}
156171
157172void ProducerImpl::connectionFailed (Result result) {
@@ -167,8 +182,10 @@ void ProducerImpl::connectionFailed(Result result) {
167182 }
168183}
169184
170- void ProducerImpl::handleCreateProducer (const ClientConnectionPtr& cnx, Result result,
171- const ResponseData& responseData) {
185+ Result ProducerImpl::handleCreateProducer (const ClientConnectionPtr& cnx, Result result,
186+ const ResponseData& responseData) {
187+ Result handleResult = ResultOk;
188+
172189 Lock lock (mutex_);
173190
174191 LOG_DEBUG (getName () << " ProducerImpl::handleCreateProducer res: " << strResult (result));
@@ -190,7 +207,7 @@ void ProducerImpl::handleCreateProducer(const ClientConnectionPtr& cnx, Result r
190207 lock.unlock ();
191208 producerCreatedPromise_.setFailed (ResultAlreadyClosed);
192209 }
193- return ;
210+ return ResultAlreadyClosed ;
194211 }
195212
196213 if (result == ResultOk) {
@@ -259,6 +276,7 @@ void ProducerImpl::handleCreateProducer(const ClientConnectionPtr& cnx, Result r
259276 }
260277 lock.unlock ();
261278 producerCreatedPromise_.setFailed (result);
279+ handleResult = result;
262280 } else if (producerCreatedPromise_.isComplete ()) {
263281 if (result == ResultProducerBlockedQuotaExceededException) {
264282 LOG_WARN (getName () << " Backlog is exceeded on topic. Sending exception to producer" );
@@ -269,22 +287,23 @@ void ProducerImpl::handleCreateProducer(const ClientConnectionPtr& cnx, Result r
269287
270288 // Producer had already been initially created, we need to retry connecting in any case
271289 LOG_WARN (getName () << " Failed to reconnect producer: " << strResult (result));
272- scheduleReconnection () ;
290+ handleResult = ResultRetryable ;
273291 } else {
274292 // Producer was not yet created, retry to connect to broker if it's possible
275- result = convertToTimeoutIfNecessary (result, creationTimestamp_);
276- if (isResultRetryable (result)) {
277- LOG_WARN (getName () << " Temporary error in creating producer: " << strResult (result));
278- scheduleReconnection ();
293+ handleResult = convertToTimeoutIfNecessary (result, creationTimestamp_);
294+ if (isResultRetryable (handleResult)) {
295+ LOG_WARN (getName () << " Temporary error in creating producer: " << strResult (handleResult));
279296 } else {
280- LOG_ERROR (getName () << " Failed to create producer: " << strResult (result ));
281- failPendingMessages (result , false );
297+ LOG_ERROR (getName () << " Failed to create producer: " << strResult (handleResult ));
298+ failPendingMessages (handleResult , false );
282299 state_ = Failed;
283300 lock.unlock ();
284- producerCreatedPromise_.setFailed (result );
301+ producerCreatedPromise_.setFailed (handleResult );
285302 }
286303 }
287304 }
305+
306+ return handleResult;
288307}
289308
290309auto ProducerImpl::getPendingCallbacksWhenFailed () -> decltype(pendingMessagesQueue_) {
0 commit comments