Skip to content
This repository was archived by the owner on Apr 30, 2025. It is now read-only.
This repository was archived by the owner on Apr 30, 2025. It is now read-only.

Thread leaks #169

@2rba

Description

@2rba

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions