You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
flush() previously waited indefinitely on the internal queue, which could block short-lived Celery/serverless workloads if the queue never drained. This adds a bounded wait by default while preserving the old behavior with timeout_seconds=None.
💚 How did you test it?
uv run --extra test pytest posthog/test/test_client.py posthog/test/test_module.py -q
uv run --extra test pytest posthog/test/test_client.py::TestClient::test_shutdown posthog/test/integrations/test_celery_integration.py -q
uv run --extra test pytest posthog/test/test_client.py::TestClient::test_flush_timeout_returns_when_queue_does_not_drain posthog/test/test_client.py::TestClient::test_flush_logs_and_returns_on_unexpected_error posthog/test/test_client.py::TestClient::test_shutdown_flushes_without_timeout -q
uv run --extra dev ruff check posthog/client.py posthog/__init__.py posthog/test/test_client.py posthog/test/test_module.py
uv run --extra dev mypy posthog/client.py posthog/__init__.py --config-file mypy.ini
uv run --extra dev make public_api_check
📝 Checklist
I reviewed the submitted code.
I added tests to verify the changes.
I updated the docs if needed.
No breaking change or entry added to the changelog.
If releasing new changes
Ran sampo add to generate a changeset file
🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Implemented with the pi coding agent. The change is intentionally small: flush() now accepts timeout_seconds with a 10 second default, uses the queue condition variable to avoid indefinite blocking, logs on timeout, and keeps indefinite waiting available via timeout_seconds=None. Review feedback was addressed by making flush() defensive, preserving shutdown()'s indefinite flush behavior, marking the release as a minor feature, and updating the public API snapshot.
shutdown() now silently drops events: it calls self.flush() with no argument, which picks up the new 10-second default. shutdown()'s documented contract is "Flush all messages… to avoid data loss," but if consumers haven't finished within 10 seconds the remaining events are silently discarded. Pass timeout_seconds=None here so shutdown() keeps its original "wait indefinitely" guarantee, while direct flush() callers still get the bounded timeout.
Prompt To Fix With AI
This is a comment left during a code review.
Path: posthog/client.py
Line: 1496-1497
Comment:
`shutdown()` now silently drops events: it calls `self.flush()` with no argument, which picks up the new 10-second default. `shutdown()`'s documented contract is "Flush **all** messages… to avoid data loss," but if consumers haven't finished within 10 seconds the remaining events are silently discarded. Pass `timeout_seconds=None` here so `shutdown()` keeps its original "wait indefinitely" guarantee, while direct `flush()` callers still get the bounded timeout.
How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.
---### Issue 1 of 2
posthog/client.py:1496-1497
`shutdown()` now silently drops events: it calls `self.flush()` with no argument, which picks up the new 10-second default. `shutdown()`'s documented contract is "Flush **all** messages… to avoid data loss," but if consumers haven't finished within 10 seconds the remaining events are silently discarded. Pass `timeout_seconds=None` here so `shutdown()` keeps its original "wait indefinitely" guarantee, while direct `flush()` callers still get the bounded timeout.
```suggestion self.flush(timeout_seconds=None) self.join()```### Issue 2 of 2
posthog/test/test_client.py:144-157
Potential race condition in new test: a live consumer thread may dequeue and call `task_done()` on the manually-inserted item before `flush()` is called, making the queue appear empty and causing `assertFalse(client.queue.empty())` to fail intermittently. Consider using `threads=0` (or the equivalent config to disable background consumers) when constructing this test client so the queue item is guaranteed to stay unprocessed for the duration of the timeout check.
Addressed Greptile feedback in 7d3a956: shutdown() now calls flush(timeout_seconds=None) to preserve its indefinite wait contract, and the timeout test now uses thread=0.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
💡 Motivation and Context
Fixes #79.
flush()previously waited indefinitely on the internal queue, which could block short-lived Celery/serverless workloads if the queue never drained. This adds a bounded wait by default while preserving the old behavior withtimeout_seconds=None.💚 How did you test it?
uv run --extra test pytest posthog/test/test_client.py posthog/test/test_module.py -quv run --extra test pytest posthog/test/test_client.py::TestClient::test_shutdown posthog/test/integrations/test_celery_integration.py -quv run --extra test pytest posthog/test/test_client.py::TestClient::test_flush_timeout_returns_when_queue_does_not_drain posthog/test/test_client.py::TestClient::test_flush_logs_and_returns_on_unexpected_error posthog/test/test_client.py::TestClient::test_shutdown_flushes_without_timeout -quv run --extra dev ruff check posthog/client.py posthog/__init__.py posthog/test/test_client.py posthog/test/test_module.pyuv run --extra dev mypy posthog/client.py posthog/__init__.py --config-file mypy.iniuv run --extra dev make public_api_check📝 Checklist
If releasing new changes
sampo addto generate a changeset file🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Implemented with the pi coding agent. The change is intentionally small:
flush()now acceptstimeout_secondswith a 10 second default, uses the queue condition variable to avoid indefinite blocking, logs on timeout, and keeps indefinite waiting available viatimeout_seconds=None. Review feedback was addressed by makingflush()defensive, preservingshutdown()'s indefinite flush behavior, marking the release as a minor feature, and updating the public API snapshot.