fix!: derive provider status from a single ordered event relay - #259
Closed
mtonko-flx wants to merge 2 commits into
Closed
fix!: derive provider status from a single ordered event relay#259mtonko-flx wants to merge 2 commits into
mtonko-flx wants to merge 2 commits into
Conversation
Spec requirement 5.1.1 requires the provider event set to include PROVIDER_RECONCILING and PROVIDER_CONTEXT_CHANGED, and 5.2.3 requires event details to carry the provider name. Neither existed, so the SDK could not represent context reconciliation as events nor attribute an event to its provider. Signed-off-by: Mark Tonkonoh <mark.tonkonoh@fluxon.com>
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: trueComment |
BREAKING CHANGE: statusFlow is now StateFlow<OpenFeatureStatus> and conflates consecutive equal values. Signed-off-by: Mark Tonkonoh <mark.tonkonoh@fluxon.com>
mtonko-flx
force-pushed
the
fix/single-ordered-event-relay
branch
from
August 28, 2026 11:22
a4fe576 to
8d0565f
Compare
This was referenced Aug 28, 2026
Author
|
Superseded by #262, which delivers this work as a single change. Closing the stack. |
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.
Intent
Provider status and provider events are two independent subscriptions to the same provider stream.
handleProviderEventscollects it to update the status, andobserve<T>()hands application code its own subscription — so nothing orders the two, and a handler can observe an event before the status reflects it. SDK-inferred transitions also never appear in the event stream at all. This PR makes the SDK collect the provider once, write the status, and only then republish, so the status is always current by the time subscribers see the event that caused it.Motivation
Requirement 5.3.5 requires the status be updated before the handlers for that event run; with two independent subscriptions that cannot be guaranteed. Requirement 5.3.3 requires a handler attached when the provider is already in a state to run immediately, which nothing currently provides. Both are prerequisites for spec #385, where the status is derived entirely from provider events.
It also closes the gap raised on spec #365 that Kotlin's
observeis a straight passthrough to the provider, so lifecycle events aroundsetProvider/setEvaluationContextnever appear in it.Spec Requirements
RECONCILINGNOT_READYonceshutdownterminatesPROVIDER_NOT_READY)Changes
Implementation
provider.observe(): stamps the provider name, writes the status from the event, then republishes onto an SDK-ownedMutableSharedFlowthatobserve<T>()reads.tryEmitagainst a bounded buffer, so a slow application subscriber can never stall the SDK's own status derivation — requirement 1.1.2.4 notes application handlers need not complete. Overflow drops the oldest and logs.PROVIDER_CONFIGURATION_CHANGED, or an event belonging to a provider that has since been replaced.statusFlowbecomes aStateFlow;getStatus()reads.valueinstead of a replay cache.NOT_READY/FATAL short-circuit
Requirements 1.7.6/1.7.7 as they stood — the client short-circuiting evaluation while
NOT_READY/FATAL— were removed by #385 and retagged@spec-2.2.7, on the grounds that reading the status and then evaluating is itself a time-of-check/time-of-use gap (spec #369). They were removed rather than inverted, so short-circuiting remains permitted. This SDK keeps it: dropping it would change the error codes callers already depend on, andEvaluationStatesnapshots the provider and context together, which bounds the staleness. Only the KDoc changes, to record that this is now deliberate policy rather than a requirement.Testing
READY— and separately whileSTALE— receives that state's event immediately; a statelessCONFIGURATION_CHANGEDis not resurfaced, nor is an event from a replaced provider (5.3.3).shutdownreverts toNOT_READYwithout putting an event into the stream (1.7.6).ktlintCheckandapiCheckgreen,apiDumpregenerated.Two pre-existing test weaknesses surfaced and were corrected rather than worked around: several event tests launched a collector and then registered a provider before it had subscribed, passing only because the provider's own flow replayed; and status-sequence assertions relied on the relay running in real time. Both now subscribe first and drive the relay on the test dispatcher.
Breaking Changes
statusFlowis nowStateFlow<OpenFeatureStatus>rather thanFlow<OpenFeatureStatus>, and conflates consecutive equal values — status is a snapshot, and the transition sequence belongs toobserve<T>(). Source-compatible for collection; binary-incompatible, and code asserting on every intermediate status should move to the event stream.