Async client memory leak
bale-john opened this issue · 0 comments
Hi guys,
I hope this message finds you well. I encountered a memory leak issue while using HeaderClientChannel in my code. The version I'm using is 2021.03.08.00.
Here's my usage pattern:
template <class AsyncClient>
std::shared_ptr<AsyncClient> RpcClientMan<AsyncClient>::CreateClient(
folly::EventBase* evb, folly::SocketAddress addr, uint32_t timeout_ms,
int32_t retry) {
std::shared_ptr<apache::thrift::RequestChannel> channel =
apache::thrift::ReconnectingRequestChannel::newChannel(
*evb,
[protocol_type = opts_.protocol_type, protocol_id = opts_.protocol_id,
addr, timeout_ms](folly::EventBase& eb) mutable {
std::shared_ptr<folly::AsyncSocket> socket;
eb.runImmediatelyOrRunInEventBaseThreadAndWait(
[&socket, &eb, addr, timeout_ms]() {
socket = folly::AsyncSocket::newSocket(&eb, addr, timeout_ms);
});
auto headerClientChannel =
apache::thrift::HeaderClientChannel::newChannel(
std::move(socket));
if (timeout_ms > 0) {
headerClientChannel->setTimeout(timeout_ms);
}
headerClientChannel->setClientType(protocol_type);
headerClientChannel->setProtocolId(protocol_id);
return headerClientChannel;
});
channel->getProtocolId();
std::shared_ptr<AsyncClient> client(
new AsyncClient(apache::thrift::RetryingRequestChannel::newChannel(
*evb, retry, std::move(channel))),
[evb](auto* p) {
evb->runImmediatelyOrRunInEventBaseThreadAndWait([p] { delete p; });
});
return client;
}
In my unit tests, I noticed that the HeaderClientChannel object is not being destructed properly, indicating a memory leak. Additionally, while troubleshooting this memory leak, I discovered another issue.
In the ReconnectingRequestChannel class, there's a method called reconnectIfNeeded():
void ReconnectingRequestChannel::reconnectIfNeeded() {
if (!impl_ || !impl_->good()) {
impl_ = implCreator_(evb_);
}
}
This method can be accessed by multiple threads without any locking mechanism. Because client will be used by multi thread, when they send a message for the first time, they will invoke this method. Could this potentially lead to thread safety issues?
Thank you for your assistance!