Repository navigation
feat: keep events on the device until the server has them, and store each once - #14
Merged
Merged
Conversation
…th a clientEventId Each event carries a clientEventId generated when it is tracked and kept through retries, so a server that recognizes it stores an event once. The event queue is stored in SharedPreferences: an event is stored before it is sent and removed once the server has it, so unsent events survive the app being closed. Queued events are sent when initialize() completes, when the app returns to the foreground (activity lifecycle callbacks; no new permission), after the next event that sends, and on flushEvents(). Flushes run one at a time. trackEvent, trackRevenue and trackScreenView return normally when the event is queued for retry (no connection, or a 5xx); they still throw for invalid input, when not initialized, and for a 4xx rejection.
…e, and the foreground sends the queue Shared harness: the proxy can drop event requests or cut the connection after the server replies, and three scenarios check that an offline event is stored once after the app is closed and reopened, that an event whose reply was lost is stored once when resent, and that queued events go out when the app returns to the foreground. The Android device sends the app home and brings the running task back. API.md: a failed initialize() keeps registered callbacks.
Merged
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.
Summary
Events are now kept on the device until the server has them, and each carries an id the server uses to store it once.
clientEventId. Every event gets a UUID when it is tracked (trackEvent,trackRevenue,trackScreenView), sent asclientEventIdand kept through every retry.initialize().clearData()andclearEventQueue()clear it.clientEventId.initialize()completes, when the app returns to the foreground, after the next event that sends, and onflushEvents(). Flushes run one at a time, so concurrent triggers send each event once.Application.ActivityLifecycleCallbacks(started-activity count 0 → 1); the network connection is not watched, and no dependency is added.Behavior change
trackEvent,trackRevenueandtrackScreenViewreturn normally when the event can't be sent now (no connection, or a 5xx) and is queued. They used to throwNetworkError/InvalidResponsewhile queueing it. They still throw for invalid input, when not initialized, and when the server rejects the event (4xx); a rejected event is not kept. Listed under Changed in the CHANGELOG.Server
Storing a resent event once needs a server whose event endpoint recognizes
clientEventId(@linkforty/corewith client event ID support). An older server ignores the field; events are then delivered at least once, and a resend after a lost reply can be stored twice.Tests
DurableEventsTest(9): id format and the same id on retry; different ids per event; queue restored by a new tracker with integers and nested values intact; stored before sent; a 4xx throws and is not kept; clearing clears storage; four concurrent flushes send three events exactly once; an unreadable stored queue is discarded; the id survives storage.EventTrackerTest: returns normally on a 5xx and offline.EventTracker.ktreverted, since the tests use the new storage API): 8 of those tests fail.eventQueuedOnServerErrorsSurvivesARelaunchAndIsSentOnceWithTheSameId: three 503s,trackEventreturns normally, then after a relaunch the event is sent once with the same id.e2e/run.mjs, emulator + Chrome, local server with the new Core): 76 passed, 0 failed. New scenarios in the shared harness: an event tracked offline survives the app closing and is stored once; an event whose reply is lost is stored once when it is sent again; queued events are sent when the app returns to the foreground, without a new launch.Also: API.md no longer says to register callbacks again after a failed
initialize()(they're kept since 1.4.0).