Skip to content

fix: Add sync_mode for Sidekiq/Resque compatibility#112

Merged
haacked merged 4 commits intomainfrom
haacked/issue-10-review
Mar 16, 2026
Merged

fix: Add sync_mode for Sidekiq/Resque compatibility#112
haacked merged 4 commits intomainfrom
haacked/issue-10-review

Conversation

@haacked
Copy link
Contributor

@haacked haacked commented Mar 16, 2026

Summary

  • Add sync_mode option that sends events synchronously on the calling thread, bypassing the background queue entirely
  • Follows the same pattern as the Python SDK: each event is sent inline via Transport#send at capture time
  • Fixes event loss in forking environments (Sidekiq, Resque) where background threads are killed on fork

Usage

PostHog::Client.new(api_key: 'key', sync_mode: true)

Or with Rails:

PostHog.init do |config|
  config.api_key = 'key'
  config.sync_mode = true
end

Design

  • sync_mode bypasses the queue and worker entirely — no SyncWorker class needed
  • enqueue calls send_sync which creates a single-item MessageBatch and sends it immediately
  • flush is a no-op in sync mode (nothing to flush)
  • test_mode takes precedence over sync_mode
  • Transport is initialized with 3 retries for resilience

Test plan

  • New specs verify sync sends without queue/worker, error handling, serialization failures, and test_mode precedence
  • Full test suite passes (326 specs, 0 failures)
  • Manual testing with Sidekiq/Resque to confirm events are delivered reliably

Fixes: #10

Note

Issue #10 is a blocker for some customers to adopt our library rather than rolling their own code.

@haacked haacked requested a review from Copilot March 16, 2026 19:56
@haacked haacked changed the title Add sync_mode for Sidekiq/Resque compatibility fix: Add sync_mode for Sidekiq/Resque compatibility Mar 16, 2026
@haacked haacked requested review from a team and rafaeelaudibert March 16, 2026 19:58

This comment was marked as resolved.

Send events synchronously on the calling thread instead of queuing
them for a background worker. Follows the same pattern as the Python
SDK: in sync_mode, events bypass the queue entirely and are sent
inline via Transport#send.

Retries are capped at 3 in sync mode (vs 10 in async) to avoid
blocking the calling thread for extended periods during API outages.

test_mode takes precedence over sync_mode to prevent accidental
network calls in test environments.

Usage: PostHog::Client.new(api_key: 'key', sync_mode: true)

Fixes #10
@haacked haacked force-pushed the haacked/issue-10-review branch from 850b75f to 0cba1cd Compare March 16, 2026 20:31
Copy link
Contributor

@dustinbyrne dustinbyrne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems totally reasonable to me. The Copilot comment regarding exceptions in example.call is nit-picky but seems worth considering.

@haacked haacked marked this pull request as ready for review March 16, 2026 21:28
@haacked haacked requested a review from Copilot March 16, 2026 21:28

This comment was marked as resolved.

@haacked
Copy link
Contributor Author

haacked commented Mar 16, 2026

The Copilot comment regarding exceptions in example.call is nit-picky but seems worth considering.

As I told Copilot, this is a false positive. RSpec's around hook captures test failures internally. example.call doesn't raise, so the cleanup after it always runs. This is the same pattern used across the entire test suite (e.g., send_worker_spec).

This comment was marked as resolved.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an opt-in sync_mode to the Ruby client so event capture can send immediately on the calling thread (bypassing the queue/worker), improving reliability in forking job systems like Sidekiq/Resque.

Changes:

  • Add sync_mode option to PostHog::Client that sends each event inline via Transport#send, with locking for in-flight sends and flush as a no-op (wait-only) in sync mode.
  • Add Rails initializer support for config.sync_mode.
  • Add worker shutdown plumbing (noop + send worker) and bump gem version to 3.6.0, plus new specs for sync-mode behavior.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.

Show a summary per file
File Description
spec/posthog/client_spec.rb Adds specs covering sync-mode inline send, error handling, serialization failure, flush behavior, and test_mode precedence.
posthog-rails/lib/posthog/rails/railtie.rb Exposes sync_mode configuration via Rails init config wrapper.
lib/posthog/client.rb Implements sync_mode (inline send path, transport init, flush/shutdown coordination) and documents the new option.
lib/posthog/send_worker.rb Adds shutdown method used by client shutdown flow.
lib/posthog/noop_worker.rb Adds shutdown no-op to match worker interface.
lib/posthog/version.rb Bumps version to 3.6.0.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@haacked haacked merged commit fdedc30 into main Mar 16, 2026
17 of 18 checks passed
@haacked haacked deleted the haacked/issue-10-review branch March 16, 2026 22:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Posthog ruby does not work in background job systems like Sidekiq and Resque

3 participants