Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: move initialization into class methods, limit singleton use #170

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

typotter
Copy link
Collaborator

@typotter typotter commented Feb 11, 2025


labels: mergeable

Eppo Internal
🎟️ towards FF-3888
πŸ“œ Multiple Eppo Clients
Configuration Side-loading

Motivation and Context

This PR is carved from #166 in an attempt to make #166 focused on the the "new" API. This PR adds no net new functionality, however, the new EppoJSClient.init method, marked @internal does allow for unbuffered initialization calls just as the global init method previously allowed. This internal method can be made private once we remove the global init method in the next major release.

The init and getInstance() methods work on a singleton instance of the EppoJSClient which makes for a generally smooth developer experience given that the Eppo SDK essentially handles dependency management for the dev. This does have its own drawbacks, but those are not particularly relevant here.

There are use cases, however, when a non-singleton instance of the EppoJSClient is required. One such use case is embedding the Eppo SDK into a library which itself can be included in other applications. If that 3p library shipped with Eppo is integrated into another application that has the Eppo SDK running, there would be undefined behaviour as the SDK cannot handle this use case.

TL;DR: We want to move away from singleton access and allow for multiple instance of the EppoJSClient while maintaining the current API

Description

  • Move bulk of initialization to a class method
  • funnel all references to the static instance through getInstance()
  • deprecate EppoJSClient.instance
  • make initialized and ensureInitialized class members; still set EppoJSClient.initialized as before to ensure backward compatibility with the current API

How has this been documented?

  • doc comments

How has this been tested?

  • tests

@@ -287,308 +584,42 @@ export function buildStorageKeySuffix(apiKey: string): string {
* @public
*/
export function offlineInit(config: IClientConfigSync): EppoClient {
const isObfuscated = config.isObfuscated ?? false;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

moved to class

return client;
}

async function explicitInit(config: IClientConfig): Promise<EppoClient> {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

moved to EppoJSClient.init

@typotter typotter changed the title Typo/no singleton chore: move initialization into class methods, limit singleton use Feb 11, 2025
@typotter typotter marked this pull request as ready for review February 11, 2025 23:31
src/index.ts Outdated
* @internal
* @param config
*/
async init(config: IClientConfig): Promise<EppoJSClient> {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

no changes here from explicitInit

* @internal
* @param config
*/
offlineInit(config: IClientConfigSync) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

no changes from offline init

: initFromConfigStoreError
? initFromConfigStoreError
: new Error('Eppo SDK: No configuration source produced a valid configuration');
applicationLogger.warn(
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The diff makes it hard to see what's left in this method;

  1. We keep the forceReinitialize check here to keep it out of the EppoJSClient.init method
  2. Warn if an initialization is currently in progress

@felipecsl
Copy link
Member

Just a thought here, since this will require a major version bump, does it even make sense to deprecate the old APIs?

Since we're doing a major departure in terms of API design, it might not make sense to keep deprecated APIs around, as that will make the internal design a lot more complicated.

Since upgrading will require code changes anyways (assuming it will be a major bump), then we might as well just redesign it as a blank slate, not worrying about deprecations. WDYT?

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.

2 participants