Problem
phobos uses Thread.current[NAMESPACE] thread to save a reference to async_producer
Therefore, it causes threads(memory) leaks in a multithreaded environments (Sidekiq, puma).
code to reproduce
p Thread.list.size => 5
Thread.new {Deimos::Backends::KafkaAsync.execute(producer_class: Struct.new(:topic).new, messages: [])}.join
p Thread.list.size => 7
Thread.new {Deimos::Backends::KafkaAsync.execute(producer_class: Struct.new(:topic).new, messages: [])}.join
p Thread.list.size => 9
Suggestion
As ruby-kafka is multithread safe it makes sense to have one instance of async producer per process.
https://github.com/zendesk/ruby-kafka?tab=readme-ov-file#thread-safety
the asynchronous producer should be safe to use in a multi-threaded environment. This is because producers, when instantiated, get their own copy of any non-thread-safe data such as network sockets. Furthermore, the asynchronous producer has been designed in such a way to only a single background thread operates on this data while any foreground thread with a reference to the producer object can only send messages to that background thread over a safe queue. Therefore it is safe to share an async producer object between many threads.
This fixes the leak, reduces memory usage and potentially improves performance as messages might be sent in batches.
this can be achieved by updating create_async_producer and async_producer methods https://github.com/phobos/phobos/blob/master/lib/phobos/producer.rb#L141
as
def create_async_producer
client = kafka_client || configure_kafka_client(Phobos.create_kafka_client(:producer))
@async_producer = client.async_producer(**async_configs)
end
# @return [Kafka::AsyncProducer]
def async_producer
@async_producer
end
Problem
phobosusesThread.current[NAMESPACE]thread to save a reference toasync_producerTherefore, it causes threads(memory) leaks in a multithreaded environments (Sidekiq, puma).
code to reproduce
Suggestion
As
ruby-kafkais multithread safe it makes sense to have one instance of async producer per process.https://github.com/zendesk/ruby-kafka?tab=readme-ov-file#thread-safety
This fixes the leak, reduces memory usage and potentially improves performance as messages might be sent in batches.
this can be achieved by updating
create_async_producerandasync_producermethods https://github.com/phobos/phobos/blob/master/lib/phobos/producer.rb#L141as