Skip to content

Conversation

@MattIPv4
Copy link
Member

@MattIPv4 MattIPv4 commented Nov 25, 2025

This PR

Adds a new options argument when calling setProvider and setProviderAndWait in the web SDK, allowing for a context validation method to be provided. This method can cause the initialization of the provider to be skipped when setting a new provider, leaving it NOT_READY, until a future valid context change is made. It can also cause context change reconciliation to be skipped.

Related Issues

Resolves #1279

Notes

While returning false during context validation will prevent a provider from reconciling context changes, the updated context is still stored and persisted.

Follow-up Tasks

N/A

How to test

See test suite :)

@MattIPv4 MattIPv4 force-pushed the feat/delayed-provider-initialization branch 3 times, most recently from 3e3ed0f to 88a7d24 Compare November 25, 2025 22:19
@MattIPv4 MattIPv4 changed the title feat: allow delayed provider initialization until first context change feat: allow skipping initialization + context changes based on current context Nov 25, 2025
@MattIPv4 MattIPv4 changed the title feat: allow skipping initialization + context changes based on current context feat: allow validating context to skip initialization + context changes Nov 25, 2025
@MattIPv4 MattIPv4 force-pushed the feat/delayed-provider-initialization branch from 88a7d24 to ab99c5c Compare November 25, 2025 22:25
@MattIPv4 MattIPv4 marked this pull request as ready for review November 26, 2025 00:37
@MattIPv4 MattIPv4 requested review from a team as code owners November 26, 2025 00:37
@MattIPv4 MattIPv4 force-pushed the feat/delayed-provider-initialization branch from c621cda to b535a19 Compare November 26, 2025 00:39
@MattIPv4
Copy link
Member Author

/gemini review

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a validateContext option for setProvider and setProviderAndWait, allowing for more granular control over provider initialization and context reconciliation. The changes are well-implemented, with logic extracted into a new initializeProviderForDomain method in the shared package for better code reuse. The new functionality is also thoroughly tested. My feedback includes a few suggestions to reduce code duplication in event emission logic, which will improve maintainability. Overall, this is a solid contribution that adds valuable flexibility to the SDK.

Signed-off-by: MattIPv4 <me@mattcowley.co.uk>
Signed-off-by: MattIPv4 <me@mattcowley.co.uk>
Signed-off-by: MattIPv4 <me@mattcowley.co.uk>
Signed-off-by: MattIPv4 <me@mattcowley.co.uk>
Signed-off-by: MattIPv4 <me@mattcowley.co.uk>
Signed-off-by: MattIPv4 <me@mattcowley.co.uk>
Signed-off-by: MattIPv4 <me@mattcowley.co.uk>
Signed-off-by: MattIPv4 <me@mattcowley.co.uk>
Signed-off-by: MattIPv4 <me@mattcowley.co.uk>
@MattIPv4 MattIPv4 force-pushed the feat/delayed-provider-initialization branch from d919ef0 to 96f5f42 Compare December 11, 2025 17:48
@toddbaert
Copy link
Member

Hey @MattIPv4 sorry for the delay on this one. I'll give this a review and some further thought tomorrow.

Copy link
Member

@lukas-reining lukas-reining left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the long delay @MattIPv4!

I really like the idea and I think it solves an existing problem for the static-context paradigm.
My main concern is that the change does not conform to the current spec in my eyes. I might be overlooking something there. Interested in the opinion of the rest of the @open-feature/technical-steering-committee.

If my concern is correct, I would favor to make this part of the spec.
Again, I think this solves a real problem and could be a good addition to the spec.

Comment on lines +273 to +274
// If there was a validation error with the context, move the newly created provider to ERROR state.
// We know we've skipped initialization if this happens, so no need to worry about the promise changing the state later.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The spec says [1]:

The client's provider status accessor MUST indicate ERROR if the initialize function of the associated provider terminates abnormally.

The non-normative part says:

If the provider has failed to initialize, the provider status should indicate the provider is in an error state.

So I think it is acceptable to set the state to ERROR if the initialize has not been run at all due to invalid context. But I am not 100% sure @toddbaert.

Copy link
Member Author

@MattIPv4 MattIPv4 Dec 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think setting the state to ERROR if the context has been determined to be invalid would break the purpose of this PR, as that would not allow you to suspend until the provider is ready?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh sure, I was mislead by

If there was a validation error with the context, move the newly created provider to ERROR state.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see -- the validation throws an error, it'll move to the ERROR state. If the validation successfully returns false, initialization is just skipped.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see -- the validation throws an error, it'll move to the ERROR state. If the validation successfully returns false, initialization is just skipped.

That makes sense to me.

this._logger.debug(
`Skipping context change for domain '${domain ?? 'default'}' due to validateContext returning false.`,
);
return;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returning here makes provider.onContextChange not being called.
While this makes sense if the context is invalid, I think this is not conformant to the spec.
The spec says [1]:

> When the global evaluation context is set, the on context changed function MUST run.

The SDK implementation must run the on context changed function on all registered providers that use the global evaluation context whenever it is mutated.

With this implementation, the context is still mutated [2] but the handler is not run.
While this is logical this is unexpected regarding the spec.

My feeling is we would need to add it to the spec before implementing it this way but I could be on the wrong track @open-feature/technical-steering-committee

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not mutating the context would be a problem too.
In that case it could happen that validateContext is set for the default domain. If there was a context set on the default domain which is invalid for the default domain, that is also expected to be used by a domain scoped provider, the validateContext of the default context could determine the context to be invalid while it is valid for domain scoped provider.
So not mutating would also not be an option from my point of view.

Having that said, I still think we would need to adapt the spec for this feature to be compliant.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, yes, I suspect this may need a spec change then. I don't see a great way to do this that would be compliant with what you've outlined in the spec currently.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay let's wait for feedback of the rest of the TC.

Copy link
Member

@toddbaert toddbaert Jan 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the default context could determine the context to be invalid while it is valid for domain scoped provider.

I think this is a key problem.

With respect to multiple domains, we need to decide:

  • if a validation func returns false for only a subset of domains, what happens?
    • probably it's best for this subset to remain NOT_READY, right?
  • if a validation func throws for only a subset of domains, should setProviderAndWait throw? consistent with initialization errors?
    • this means some providers will be READY and some will be ERROR
    • the other option is to consider every provider in ERROR state here, but that's not consistent with the first point above

As @lukas-reining says, this seems complex enough to require specification.

And as always, the question remains... is it better to simply avoid this addition, and push this responsibility down to providers. I know it's not ideal, but there's a complexity trade-off here as we can see.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a domain has a validation function, it also has its own context, so that does reduce the surface area we need to think about here. So, I think all we need to worry about is what happens when the default domain has a validation function, and another domain is reliant on the default domain context...

I think what the current code does there is maybe logical, in that the validation function just runs against the default domain, and the default context is only updated if the validation succeeds -- other domains have no "insight" into this, and only see the context change when the default domain decides it has a valid context change to process?

I do agree this'll need a spec change though, and I would ask for help on that as I'm not sure I know the intricacies well enough to propose a spec change for this.

I suppose the alternative would be to leave this to providers, though from experience (this is what we do currently, which prompted this PR), there isn't a particularly nice way to do this beyond essentially having initialize be a Promise that hangs for a super long time.

Co-authored-by: Lukas Reining <lukas.reining@codecentric.de>
Signed-off-by: Matt Cowley <me@mattcowley.co.uk>
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.

[FEATURE] Ability to suspend until provider context ready

3 participants