Conversation
|
Merging to
After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here |
🤖 CI report✅ Trunk lane — non-backend lane (
|
| File | Comment lines | Added lines |
|---|---|---|
rust/feature-flags/src/flags/flag_matching.rs |
9 | 97 |
rust/feature-flags/src/config.rs |
7 | 14 |
rust/feature-flags/src/utils/deadline.rs |
4 | 21 |
rust/feature-flags/src/api/batch_flag_evaluation.rs |
3 | 3 |
rust/feature-flags/src/flags/test_flag_matching.rs |
2 | 96 |
rust/feature-flags/src/handler/canonical_log.rs |
2 | 5 |
rust/feature-flags/tests/test_flags.rs |
2 | 55 |
rust/feature-flags/src/api/errors.rs |
1 | 8 |
This check does not block merging. It updates on every push and clears when the share drops.
🦔 PostHog Review reviewed this pull requestFound 0 must fix, 2 should fix, 1 consider. Published 3 findings (view the review). Resolved comments: 3 left for you |
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: PostHog/posthog/.coderabbit.yaml Review profile: QUIET Plan: Enterprise Run ID: 📒 Files selected for processing (7)
Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 9 remain after this review. 📝 WalkthroughWalkthroughThe changes add a configurable shared deadline for persons-database calls during live flag evaluation. The matcher applies it to hash-key override operations and property fetches, and reports deadline errors by operation. Expired calls produce partial flag results, while batch matching does not use this deadline. Tests cover stalled database calls and the resulting flag and error responses. Priority: ⬇️ Low Merge Risk: 🟡 Moderate · up to The deadline preserves partial results during database stalls, but flags depending on a timed-out flag can report misleading successful values. Resolve dependency-error propagation before merging, or explicitly accept this bounded correctness risk. Security Architecture ReviewSecurity architecture risk: 🟡 Moderate · up to The deadline improves outage isolation, but a flag can return a successful-looking result after its prerequisite times out. Database cancellation also has unresolved recovery behavior. No authorization bypass or cross-tenant access expansion was established. Retained concerns
Security review detailsSecurity Blast Radius
Security Findings and Attack Paths
Trust Boundaries and Controls
Resilience and Maintainability Implications
Hardening Proposals
🚥 Pre-merge checks | ✅ 1✅ Passed checks (1 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
|
|
PostHog Review alpha 🦔 If you find any issues helpful - please reply "valid", "invalid", etc., for evaluation purposes 🙏 |
|
[High risk] Adds request-scoped timeout to persons database operations. The PR should not merge until coalesced group-mapping fetches stop timing out requests before their own deadlines. Reviews (1) · Last reviewed commit: "fix(flags): bound persons db work with a..." |
b6b47dd to
096445d
Compare
Add PERSONS_DB_DEADLINE_MS (default 2500ms, 0 disables). All persons DB calls in one flag evaluation share this deadline: the hash key override check, write, and read, and the person, cohort, and group properties fetch. When it passes, the call fails with timeout:persons_db_deadline and the existing degrade path errors only the flags that need persons data. A persons database that stops answering now yields a partial 200 instead of a 503 at the request timeout. A call that would start after the deadline fails without taking a connection. The deadline wrapper boxes each persons DB future, so the /flags handler future stays within a 2 MiB stack in debug builds. Expiries increment flags_database_error_total with timeout_type="persons_db_deadline" and the call's operation, and set persons_db_deadline_exceeded on the canonical log line. Other properties fetch errors also increment flags_database_error_total, under operation fetch_properties. The internal batch evaluation endpoint does not apply the deadline, because Django drops a person whose evaluation errors from the static cohort without failing the run.
096445d to
c6a8c40
Compare
Problem
/flagsget a 503 for every flag after the 4.5s request timeout, including flags that never read persons data.statement_timeoutcannot cancel a query on a database that has stopped answering.statement_timeout, and the calls run in sequence.Changes
errorsWhileComputingFlags: truewithin the deadline. Only flags that need persons data fail, withreason.codeset totimeout:persons_db_deadline.PERSONS_DB_DEADLINE_MS(default 2500, 0 disables) sets one deadline for all persons DB calls in a/flagsevaluation.Instant, so sequential calls cannot add up past it. The default leaves 2s of the 4.5s request timeout for the rest of the request.timeout_atalone would start the call and then abandon it.flags_database_error_totalcounter withtimeout_type="persons_db_deadline"and itsoperation.flags_database_error_totalunderoperation="fetch_properties". Before, only the hash key calls reported there.persons_db_deadline_exceededrecords the first stopped call.before_persons_db_deadlineboxes each persons DB future. Without the box, the wrapper layers grow the/flagshandler future past the 2 MiB debug test stack.before_deadlineinutils/deadline.rsandbefore_persons_db_deadlineinflag_matching.rs. The rest is wiring and tests.Before:
After:
Note
This PR stacks on #108014 and must merge after it. #108014 sets the persons reader statement timeout to 1000ms, the writer statement timeout to 2000ms, and the acquire timeout to 1s. Each sits below the 2.5s deadline, so Postgres cancels an ordinary slow query before the deadline drops it. Without #108014, the deadline would drop 2.5 to 3s queries that finish today, and each dropped query keeps its connection until sqlx's release ping finishes.
Known limits:
timeout:pool_timeout. Dashboards should count both codes.flag_evaluates_toreturns a normal-looking value, with nofailed: true, when the persons flag errors. That behavior is unchanged, but a stall now reaches it through a 200.How did you test this code?
test_stalled_persons_db_degrades_within_one_deadlineruns with and without$anon_distinct_id, on paused time, against a fake database that never answers. It fails if a call loses its deadline (hang), if each call gets its own timeout, or if a call starts after the deadline.persons_db_deadline_exceededlog field. It fails if the log records a later call than the first one stopped.it_degrades_person_flags_when_the_persons_db_stops_answeringruns the real server with the persons read URL pointed at a socket that never replies. It fails if the config does not reach the matcher.it_rejects_invalid_tokenpasses at a 1.75 MiB stack and overflows at 1.6875 MiB, the same as the merge base. CI on Linux is the real check.posthog_personreturns a 200 with person flags attimeout:persons_db_deadline.flags_database_error_totaland the canonical log field name the stopped call.PERSONS_DB_DEADLINE_MS=0, the same lock returnstimeout:query_canceledat the 3s statement timeout.timeout:persons_db_deadline.errors_count: 0.👉 Stay up-to-date with PostHog coding conventions for a smoother review.
Release status
Automatic notifications
Docs update
docs/internal/feature-flags/database-interaction-patterns.md. No public docs change.🤖 Agent context
Autonomy: Human-driven (agent-assisted)
Agent: Claude Code, Claude Opus 5.5 (
claude-opus-5-5)/writing-tests,/writing-code-comments,/reviewing-with-coderabbit,/writing-pr-descriptions,/review-code,/simplify,/stacking-prs.--deep, three findings. Two duplicates asked to lower the persons statement timeouts below the deadline, which fix(flags): fit db timeouts inside the request timeout #108014 does. The third concerned the group type cache and moved with that code to fix(flags): apply the persons db deadline to the group type lookup #108772./review-code --fixpass found that the earlier pushes overflowed the stack in 47 feature-flags integration tests. Fixed by boxing the persons DB future inbefore_persons_db_deadline. The same pass extended the stall test./simplifyreplaced a dedicatedflags_persons_db_deadline_exceeded_totalcounter withflags_database_error_total. Deadline stops now share one counter and one set of operation names with other persons DB errors.