trunk-merge/pr-89410/864f07c1-41d9-46e5-94d4-a7a713dd5313 - #89650
Closed
trunk-io[bot] wants to merge 380 commits into
Closed
trunk-merge/pr-89410/864f07c1-41d9-46e5-94d4-a7a713dd5313#89650trunk-io[bot] wants to merge 380 commits into
trunk-io[bot] wants to merge 380 commits into
Conversation
Person-property and account-property projection lookups now retry once on a transient app-DB connection drop (OperationalError/InterfaceError), reusing the existing aretry_on_db_connection_drop helper. Previously a stale pooled connection propagated straight to materialize_view.py's catch-all, which reported it to error tracking and silently skipped that run's property sync. Generated-By: PostHog Desktop Task-Id: f08526a4-2e19-4806-940c-1c228471fac4
Generated-By: PostHog Desktop Task-Id: f1ac2634-4ae4-4683-92b3-54e332b641bc
Generated-By: PostHog Desktop Task-Id: f1ac2634-4ae4-4683-92b3-54e332b641bc
Adds INGESTION_TRANSPORT=http|grpc. On grpc, each worker gets one ordered WorkerIngest stream: enqueue order is wire order is the worker's feed order, closing the reordering window concurrent HTTP requests leave open. Sends become two-phase on both transports: begin_send establishes send order synchronously where order is decided (the consumer loop after assignment, the serialized flush paths, the eager loop) and wait resolves like an HTTP response. HTTP implements begin_send lazily, so its behavior is unchanged. A nack, stream break, or connect failure fences the lane: every un-acked and queued sub-batch resolves as failed in enqueue order with its messages, so the existing deferral path stashes them, holds all newer work for those keys, and retries the failed group first. Lanes reconnect with backoff and a bumped stream_epoch; rebalances bump assignment_epoch — both scope the worker's feed-order sentinel.
The stream has no per-send timeout, so a worker that stops acking (saturated, wedged, half-dead network) left un-acked sub-batches waiting forever and wedged the whole consumer — the failure mode HTTP surfaced as a request timeout. A watchdog now fences the lane when un-acked work sees no ack for INGESTION_LANE_ACK_TIMEOUT_MS (default 60s): everything outstanding fails back into the deferral path in order and re-routes. The deadline advances on every ack, so a slow-but-progressing worker is never fenced.
… mode Adds GrpcPort::OffsetFromHttp (each worker's stream address is its HTTP port plus an offset, INGESTION_WORKER_GRPC_PORT_OFFSET) so single-host setups — the e2e harness and local dev — can address many workers on one IP. The e2e FakeWorker now serves WorkerIngest on its HTTP port + 1, and two e2e scenarios run the full Kafka → lane → ack → commit loop over gRPC: per-distinct_id ordering, and a nacking worker fencing its lane and rerouting in order.
…m setup The worker now greets each stream with a reserved seq-0 ack to flush response headers (see the worker-side fix); the lane ignores it instead of fencing on an unknown seq. Connect and stream-open are now bounded by the lane ack timeout — a worker that never greets (or a non-h2 endpoint that accepts TCP) fences and re-routes instead of hanging the lane forever, which is how production wedged. Lane logs carry the dialed grpc_url so a wrong address is a one-line diagnosis.
Add SUB_BATCH_STATUS_BUSY so a worker can signal transient backpressure distinctly from a failure. Adding an enum value is backward compatible; a consumer that predates it treats the value as unknown. Regenerate the Node stub, which CI requires to stay in sync with the proto.
Two lane-failure fixes on the gRPC transport: Reaping a worker aborted its lane task, dropping any in-flight sends unresolved. The reaper removes workers on the drain timeout whether or not they still have work, so this lost sub-batches and forced the consumer to crash and replay. Drop the lane instead: closing the queue makes the runner fence the tail in order with the messages intact, the same recovery path every other fence uses. A busy ack (SUB_BATCH_STATUS_BUSY, or any status this consumer predates) now fences as retriable backpressure rather than a fault, so the work re-routes without counting the worker unhealthy and the metric records busy instead of error. A FAILED ack still fences as a hard fault.
The worker greets each stream with a StreamReady frame and acks with SubBatchAck inside a oneof, so lanes unwrap the frame before matching on status.
…nds fail Only busy signals (HTTP 503, busy lane) are backpressure. Connection errors and 5xx are retriable too, but they are worker faults and must still count against passive health.
Share one readiness helper between the HTTP and gRPC transports. Probes carry a 5s timeout, run concurrently, and shutdown wins over a round in progress, so a worker that accepts but never answers cannot stall startup or SIGTERM.
A worker that fails sends while its readiness probe passes must degrade through passive health; the retriable-vs-fault classification at the consumer's send sites had no test.
ingestion-consumer now depends on ingestion-worker-proto, whose build script runs protoc.
Closes the backtick-quoted identifier after the dataset in get_columns's INFORMATION_SCHEMA.COLUMNS query, matching the pattern already used by get_primary_keys and get_leading_index_columns. Generated-By: PostHog Desktop Task-Id: 5863a1af-274e-410a-8f01-dd6947ed6958
…line The ack-progress watchdog used a single per-lane deadline that every OK ack reset. With more than one un-acked sub-batch, a worker that kept acking newer sub-batches but never the oldest pushed that deadline forward on each ack, so the stuck send never timed out and its Kafka batch never completed. Give each ledger entry its own deadline, armed when the sub-batch goes on the wire, and key the watchdog on the oldest (front) entry. A stuck sub-batch now fences on its own deadline even while its siblings keep acking, restoring the per-send bound the HTTP timeout it replaces provided. Adds a regression test: with the un-acked cap at 2 and a worker that acks every sub-batch except the oldest, the stuck send fences on its own deadline while a steady sibling feed continues. Generated-By: PostHog Desktop Task-Id: fd156565-dd05-4c89-8613-e97b82f92d59
The isolation skill told core test fixtures that need product rows to reach the model with apps.get_model at module scope plus a TYPE_CHECKING import, because tach ignores type-only imports. That is the same dependency with the import edge removed, not a testing door: tach, mypy and LSP stop seeing it, and snob does not select the test when the model changes, so the break lands on master instead of on the PR. The crossings scanner skips tests, which the docs read as permission for the pattern. Replace the recipe with the rule the scanner's own reasoning implies: seed product rows through the facade's write function or a product testing door, with a normal import. architecture.md and the scanner docstring say the same thing now. The two existing fixtures that use the pattern (InsightViewed, Account) are cleaned up separately.
The lane held its worker URL as a String and cloned it into the ack, ledger, and fence metric macros on the per-sub-batch and per-ack hot path, allocating a fresh String on every emission. Hold the URL as an Arc<str> so each clone is a single atomic increment, per the rust/CLAUDE.md metrics-label convention. Log macros and the metric labels are unchanged. Generated-By: PostHog Desktop Task-Id: fd156565-dd05-4c89-8613-e97b82f92d59
… acks and late enqueues Two gaps let a routing key's newer messages reach the worker ahead of older ones once a lane fenced, both live at the deployed un-acked cap (INGESTION_WORKER_CONCURRENT_BATCHES above 1). A later sub-batch's OK ack resolved at once, so its caller released the key and never replayed it; when an earlier sub-batch then failed, only the older messages were stashed and replayed, after the newer ones. The lane now records acks in its ledger and resolves only the consecutive acked prefix, so a fence still reaches an acked-but-unresolved tail and replays it in order. A fence resolved its sends before their callers had stashed the messages. In that gap the consumer loop could still enqueue a fenced key's next group, and the next stream sent it ahead of the stashed older group. Each fenced send now carries a FenceGuard that the consumer drops right after defer_failed; the lane keeps fencing every arrival until all guards from the fence are dropped, then reconnects. Adds regression tests for both, and the out-of-order ack test now asserts that a later ack waits for the earlier seq.
Scaffold two user-requested data warehouse sources as hidden stubs (unreleasedSource=True): Lovable (AI app builder) and Zenchef (restaurant reservation and management). Each adds the ExternalDataSourceType enum value, the schema-general.ts entry, a registered stub source class, a generated config, an icon, and SOURCES.md/_load_all registration. No sync logic yet. Generated-By: PostHog Desktop Task-Id: 0bfebe03-9beb-4353-9c84-1a47342d591c
The generated Kea logic type unions in sourceCatalogLogic.ts and sourceWizardLogic.tsx were out of sync with the new source types added to schema-general.ts/schema.json. This regenerates them (kea-typegen output) so the "schema.json up to date" CI check passes.
The story renders null by design, and `#storybook-root` is `display: inline-block` in the snapshot runtime, so the target collapsed to zero size and every screenshot attempt timed out. Wrap the story in a sized frame, so the snapshot still covers the null branch: caption only today, and holding the trigger beside it if the staff gate ever regresses. Also name that cause in the test runner. Playwright reported only "element is not visible" after a full 10s wait, three retries over, for both themes. Generated-By: PostHog Desktop Task-Id: ba5e6ec4-e9f7-4be9-99c9-5be55d33488e
A team that wants their product to work with PostHog AI had no doc to read. `products/posthog_ai/README.md` covered only the skills build, and the one skill about the agent — `implementing-agent-modes` — taught the frozen LangGraph runtime, down to a feature-flag example calling a helper that no longer exists. The product README is now the integration guide: where PostHog AI renders, why there is no backend integration API, and the frontend seams a team actually uses — attaching context, injecting trusted instructions, reacting to the agent's tool calls, and registering tool cards. Every snippet is copied from a real caller. The run primitives are documented as an exit hatch, not a default. `/integrating-with-posthog-ai` is the matching skill, routing to the right seam with a reference per seam for the detail and the gotchas. The skills-build docs move to `products/posthog_ai/skills/README.md`, which also gains the `sync:skill` commands the old text was missing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QN7YNd72fuG58XAwELsENt
Contributor
🤖 CI report
|
trunk-io
Bot
deleted the
trunk-merge/pr-89410/864f07c1-41d9-46e5-94d4-a7a713dd5313
branch
August 26, 2026 19:08
Author
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
This pull request was created and is being managed by Trunk Merge.
This pull request is based on the master branch at SHA c86295e66bcb7a647de548d8ff2765f62a5f1dd0.
See more details about each PR in the batch here:
When CI completes, this pull request will be closed automatically.
Pull Requests Being Tested
This pull request is testing a batch with the changes from pull requests 89410 and 88569 - batching documentation.
Dependencies
This pull request depends on the changes from pull requests 83910, 87138, 88886, 89624, 86299, 88862, and 88699.