Skip to content

feat(events): configurable eventDeliveryDelayMillis for the launch gate - #421

Open
abelonogov-ld wants to merge 1 commit into
andrey/event-durability-tier3-persistencefrom
andrey/event-delivery-delay
Open

abelonogov-ld wants to merge 1 commit into
andrey/event-durability-tier3-persistencefrom
andrey/event-delivery-delay

Conversation

@abelonogov-ld

@abelonogov-ld abelonogov-ld commented Nov 5, 2026 •

Copy link
Copy Markdown
Contributor

Requirements

  • I have added test coverage for new or changed functionality
  • I have followed the repository's pull request submission guidelines
  • I have validated my changes against all supported platform versions

Related issues

Stacked on #408 (tier 3, event persistence). This is the Android counterpart of iOS LDConfig.eventDeliveryDelay, and it closes the review gap that the start delay couldn't be configured.

Describe the solution you've provided

Adds EventProcessorBuilder.eventDeliveryDelayMillis(long). It is experimental, defaults to 2,000 ms, and is kept between 0 and 60,000 ms. It replaces the hard-coded 2 s launch delay.

  • What it holds back: after the SDK first goes online, the launch gate stays closed for this long. Until it opens, three things wait so that they don't compete with the first flag request:
    • the diagnostic init event;
    • events left from a previous run;
    • this run's periodic delivery.
  • What it doesn't hold back: an app's own flush() is never held.
  • The gate now applies with persistence off too. Before this change the gate existed only where events persist, so with persistence off the diagnostic init event went out at once. A delay of 0 opens the gate at once.
  • Pacing between batches is still persistence-only. Only persistence leaves a backlog from a previous run to spread out.
  • Gate rule: DirectEventProcessor now opens the gate from the start only when the delay is 0, rather than whenever persistence is off. Recovery of a previous run's events already delivers in either order, whether it finishes before or after the gate opens.

Tests

  • EventProcessorBuilderTest (new) covers the default and the clamping.
  • DirectEventProcessorTest:
    • The diagnostic init event waits for the gate whether or not events persist. This replaces the test that expected a wait only when persisting.
    • With no delay it goes out at once.
    • The delay set on the builder is the one the gate uses.
  • The full testDebugUnitTest run passes: 1,263 tests, 25 skipped, 0 failures, including the run without persistence.

Describe alternatives you've considered

  • Keep the gate persistence-only and make only its length configurable. That leaves the diagnostic init event competing with the first flag request when persistence is off, which is the case the review raised.
  • A separate delay for diagnostics. That adds a second setting with no clear use; both wait for the same reason.

Additional context

Behavior change: with persistence off, the diagnostic init event now goes out 2 s after going online by default, rather than at once. Apps that want the old timing can set eventDeliveryDelayMillis(0).


Note

Overview
Adds EventProcessorBuilder.eventDeliveryDelayMillis(long) (experimental, default 2s, clamped 0–60s) so apps can control how long the SDK holds back self-started traffic after first going online, mirroring iOS LDConfig.eventDeliveryDelay.

DirectEventProcessor no longer hard-codes a 2s launch delay: pacing uses the configured delay via Pacing.specified(launchDelayMillis), and the launch gate opens immediately only when the delay is 0—not when event persistence is off. Until the gate opens, the diagnostic init event, periodic flush, and (when persisting) backlog from a prior run stay off the network; flush() is never delayed. Batch gap pacing between stored batches remains persistence-only.

Notable default behavior change: with persistence disabled, the diagnostic init event now waits 2s after going online instead of sending at once; eventDeliveryDelayMillis(0) restores immediate delivery.

Tests add EventProcessorBuilderTest for defaults/clamping and extend DirectEventProcessorTest for gate timing with and without persistence.

Reviewed by Cursor Bugbot for commit 614b75d. Bugbot is set up for automated code reviews on this repo. Configure here.

Replaces the hard-coded 2 second launch delay with
EventProcessorBuilder.eventDeliveryDelayMillis (default 2s, kept between
0 and 60s, experimental). The gate now applies with persistence off too,
so the diagnostic init event no longer competes with the first flag
request; a delay of 0 opens it at once. Pacing between batches stays
persistence-only.

Co-authored-by: Cursor <cursoragent@cursor.com>
@abelonogov-ld
abelonogov-ld requested a review from a team as a code owner November 5, 2026 00:10

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant