-
Notifications
You must be signed in to change notification settings - Fork 25
Description
Problem
The posthog ruby client uses a background thread to send requests to posthog. This doesn't work in Resque or background job systems, because Resque doesn't wait for background threads to complete before completing a job.
I see this line logged, but the request is never finished.
Currently, the Client#flush method exists, but it has an arbitrary 0.1 second sleep call in it -- not ideal for a non-exit scenario.
Temporary Solution
To get posthog to send events, I had to monkeypatch PostHog::Client to run the worker in the current thread, and PostHog::Worker to not run in a continuous loop, which would block the main thread.
This is my local monkey patched code:
class PostHog::Client
def ensure_worker_running
@worker_mutex.synchronize { @worker.run_sync }
end
end
class PostHog::Worker
def run_sync
return if @queue.empty?
@lock.synchronize do
consume_message_from_queue! until @batch.full? || @queue.empty?
end
res = @transport.send @api_key, @batch
@on_error.call(res.status, res.error) unless res.status == 200
@lock.synchronize { @batch.clear }
end
endSuggested Solution
Ideally, you could configure the posthog client to do some version of the above at runtime. This way you could allow Posthog to run async if it's running in an app server context, and synchronously in a background worker context. Or, even better would be direct support for Resque or Sidekiq. There are other libraries that do something similar.