Repository navigation
feat: Deliver events with retries, a bounded buffer and a close timeout - #325
Conversation
Its entry in Flagsmith/sdk-spec's compatibility matrix at v0.9.0: `core events local-evaluation`.
…c v0.6.0 Spec v0.6.0 adds @events scenarios for getExperimentFlag, trackEvent and trackExposureEvent, plus a "Create the SDK client with events enabled" step. The SDK has supported these since 9.1.0, so the steps call the existing public API. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 6a108ea) (cherry picked from commit 9fa2ae1) (cherry picked from commit 93abd3f)
The getExperimentFlag step returned the feature name it was asked for, so the spec could not tell whether the SDK resolved the right flag. Report the evaluated flag's featureName instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit d8e4216) (cherry picked from commit deb8b37)
|
Important Review skippedBot user detected. To trigger a single review, invoke the
|
Implements event delivery as the SDK spec v0.9.0 describes it: - Retry a failed batch up to 3 times per flush, backing off from 1s, doubling, with full jitter. - Keep a batch whose last attempt finds the events API unavailable (network error, timeout, 408, 429, 502, 503, 504) for the next flush, ahead of newer events; drop it after a server error or a 4xx. - Stop tracking events once the events API refuses the environment key with a 401 or 403. - Run flushes one at a time, so a single batch is in flight. - Drop the oldest event once the buffer holds maxBuffer events, rather than flushing early. - Time out events API requests after 3 seconds by default. - Accept a timeout in `close()`, aborting the request in flight once it has passed. Wires the spec's flush, close, numbered events and local evaluation with events steps to these. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Spec v0.9.0's event delivery and close scenarios, and the local evaluation scenarios with events, failed because the SDK lacked the behaviour they describe. This push implements that behaviour in SDK changes (
Steps ( Tests Locally, all 24 spec scenarios for |
Zaimwa9
left a comment
There was a problem hiding this comment.
Requesting changes. Spec passes, but close sends a request after returning, interval flushes pile up during an outage, and removing the full-buffer send loses events above ~100/s. Please also retitle: the tracking methods are already on main.
Addresses review feedback on event delivery: - Send no further attempt once a close timeout aborts the backoff: the next attempt's request was not tied to the already aborted signal. - Skip a flush timer tick while a flush is running or queued, so ticks no longer pile up behind a batch that keeps failing. - Flush the buffer when an event is tracked while it is full, unless a batch is in flight or kept from a failed flush: only then does the new event drop the oldest one. - Retry only network errors, timeouts and 408, 429, 500, 502, 503 and 504 responses. Any other failing status drops the batch at once. - Ignore events tracked and flushes requested after `close()`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
getExperimentFlag, trackEvent and trackExposure methods|
Thanks for the review. All of it is addressed in ae69b84. Replies are on each inline comment; here are the review-level points:
Fixed. Each attempt now checks the abort signal before it sends, so a close timeout that hits during the backoff stops the retries.
Fixed. A timer tick is skipped while a flush is running or queued.
Fixed. Tracking an event into a full buffer flushes it again. The new event drops the oldest one only when a batch is in flight or kept from a failed flush. Because the flush triggers when an event arrives at a full buffer, not when the buffer reaches
Retitled to "feat: Deliver events with retries, a bounded buffer and a close timeout".
|
|
@themis-blindfold review |
|
Review failed after 2 attempt(s) (OutputError). Check the worker logs. |
The review bot didn't produce a review: it replied "Review failed after 2 attempt(s) (OutputError)", so there are no findings to address, and I haven't changed any code. The branch is still at ae69b84, which addresses your earlier review, and every check on it passes. Whether to run the bot again is up to you. |
|
@themis-blindfold review |
⚖️ Themis review: 🟠 Fix before mergeThe event processor adds bounded buffering, retries and a shutdown timeout, but its handling of HTTP 500 conflicts with the delivery requirement, and its exposure deduplication state can outlive events evicted from the buffer. The recorded CI checks passed, including the SDK specification and Node build-and-test jobs.
🟠 Majors
📝 Walkthrough
🧪 How to verify
Product take: More resilient event delivery matters for experiment measurements, especially during transient outages; accurate buffering and retry decisions are central to that benefit. 🧭 Assumptions & unverified claimsNo unverified assumptions or claims. May the next flush be uneventful · reviewed at ae69b84 |
An exposure evicted from a full buffer kept its deduplication key until the next flush started, so tracking it again during an outage discarded it although no copy remained, and keys could outgrow the buffer. Evicting or trimming an exposure now forgets its key. Restoring a kept batch rebuilds the keys from the buffer, keeping the batch's copy of an exposure tracked again while it was in flight. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The bot's review (Fix before merge) had two findings. I've replied to each inline:
|
🤖 I have created a release *beep* *boop* --- ## [9.4.0](v9.3.0...v9.4.0) (2026-11-13) ### Features * Deliver events with retries, a bounded buffer and a close timeout ([#325](#325)) ([0a9b9ed](0a9b9ed)) ### Other * **deps-dev:** bump source-map-js from 1.2.1 to 1.2.2 ([#306](#306)) ([65ae046](65ae046)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
Contributes to Flagsmith/sdk-spec#13
Contributes to Flagsmith/sdk-spec#23