Skip to content

test_mode: at_exit hook hangs forever because flush spins on non-empty NoopWorker queue #111

@lorismaz

Description

@lorismaz

Bug description

When test_mode = true is set (as recommended for test/development environments), the posthog-rails railtie registers an at_exit hook:

# posthog-rails/lib/posthog/rails/railtie.rb:111
at_exit { PostHog.client&.shutdown if PostHog.initialized? }

shutdown calls flush (in posthog-ruby/lib/posthog/client.rb):

def flush
  while !@queue.empty? || @worker.is_requesting?
    ensure_worker_running
    sleep(0.1)
  end
end

In test mode, the worker is a NoopWorker which never processes events from the queue. Any PostHog.capture call adds to the queue but nothing drains it. So flush spins in an infinite sleep(0.1) loop and the process never exits.

Impact

This affects any Rails app using posthog-rails with test_mode = true that calls PostHog.capture during tests. The test process hangs indefinitely after all tests pass, making CI pipelines stall.

Reproduction

# config/initializers/posthog.rb
PostHog.init do |config|
  config.api_key = "phc_your_key"
  config.test_mode = Rails.env.test?
end
# Any test that triggers PostHog.capture
PostHog.capture(distinct_id: "user_1", event: "test_event")
# Process will hang on exit

Suggested fix

flush should respect test_mode and skip the drain loop, or shutdown should clear the queue when using NoopWorker:

def flush
  return @queue.clear if @worker.is_a?(NoopWorker)

  while !@queue.empty? || @worker.is_requesting?
    ensure_worker_running
    sleep(0.1)
  end
end

Workaround

# test/test_helper.rb
PostHog.client.define_singleton_method(:flush) { @queue.clear }
PostHog.client.define_singleton_method(:shutdown) { @queue.clear }

Environment

  • posthog-ruby 3.5.5
  • posthog-rails 3.5.4
  • Ruby 3.4.7
  • Rails 8.1.1

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