Skip to content

Commit

Permalink
chore: expose transaction context propagation to the server sdk only (#…
Browse files Browse the repository at this point in the history
…590)

## This PR

- removes transaction context propagation from web SDK
- refactored the transaction context propagation logic to live under the
server SDK

### Notes

Transaction context propagation only makes sense on the server and was
simply ignored by the client. This removes the methods from the client
sdk to avoid confusion.

This is a **breaking change** in the web SDK. However, it's sub 1.0 and
this feature effectively had no effect if it was used. Currently, this
is not marked as a breaking change to avoid releasing a major version.
@toddbaert do you know if it's possible to mark the server sdk changes
as a chore and the web sdk changes as a breaking fix?

Signed-off-by: Michael Beemer <[email protected]>

---------

Signed-off-by: Michael Beemer <[email protected]>
  • Loading branch information
beeme1mr authored Oct 24, 2023
1 parent 5a1e7fe commit 2cdf175
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 48 deletions.
1 change: 1 addition & 0 deletions packages/server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ export * from './client';
export * from './provider';
export * from './evaluation';
export * from './open-feature';
export * from './transaction-context';
export * from '@openfeature/shared';
45 changes: 44 additions & 1 deletion packages/server/src/open-feature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ import {
objectOrUndefined,
stringOrUndefined,
} from '@openfeature/shared';
import {
ManageTransactionContextPropagator,
NOOP_TRANSACTION_CONTEXT_PROPAGATOR,
TransactionContext,
TransactionContextPropagator,
} from './transaction-context';
import { Client, OpenFeatureClient } from './client';

// use a symbol as a key for the global singleton
Expand All @@ -16,7 +22,11 @@ type OpenFeatureGlobal = {
};
const _globalThis = globalThis as OpenFeatureGlobal;

export class OpenFeatureAPI extends OpenFeatureCommonAPI<Provider> implements ManageContext<OpenFeatureAPI> {
export class OpenFeatureAPI
extends OpenFeatureCommonAPI<Provider>
implements ManageContext<OpenFeatureAPI>, ManageTransactionContextPropagator<OpenFeatureCommonAPI<Provider>>
{
private _transactionContextPropagator: TransactionContextPropagator = NOOP_TRANSACTION_CONTEXT_PROPAGATOR;
protected _defaultProvider: Provider = NOOP_PROVIDER;

private constructor() {
Expand Down Expand Up @@ -111,6 +121,39 @@ export class OpenFeatureAPI extends OpenFeatureCommonAPI<Provider> implements Ma
clearProviders(): Promise<void> {
return super.clearProvidersAndSetDefault(NOOP_PROVIDER);
}

setTransactionContextPropagator(
transactionContextPropagator: TransactionContextPropagator
): OpenFeatureCommonAPI<Provider> {
const baseMessage = 'Invalid TransactionContextPropagator, will not be set: ';
if (typeof transactionContextPropagator?.getTransactionContext !== 'function') {
this._logger.error(`${baseMessage}: getTransactionContext is not a function.`);
} else if (typeof transactionContextPropagator?.setTransactionContext !== 'function') {
this._logger.error(`${baseMessage}: setTransactionContext is not a function.`);
} else {
this._transactionContextPropagator = transactionContextPropagator;
}
return this;
}

setTransactionContext<R>(
transactionContext: TransactionContext,
callback: (...args: unknown[]) => R,
...args: unknown[]
): void {
this._transactionContextPropagator.setTransactionContext(transactionContext, callback, ...args);
}

getTransactionContext(): TransactionContext {
try {
return this._transactionContextPropagator.getTransactionContext();
} catch (err: unknown) {
const error = err as Error | undefined;
this._logger.error(`Error getting transaction context: ${error?.message}, returning empty context.`);
this._logger.error(error?.stack);
return {};
}
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EvaluationContext } from '../evaluation';
import { EvaluationContext } from '@openfeature/shared';
import { TransactionContextPropagator } from './transaction-context';

class NoopTransactionContextPropagator implements TransactionContextPropagator {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EvaluationContext } from '../evaluation';
import { EvaluationContext } from '@openfeature/shared';

/**
* Transaction context is a mechanism for adding transaction specific context that
Expand Down
1 change: 0 additions & 1 deletion packages/shared/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,5 @@ export * from './events';
export * from './logger';
export * from './provider';
export * from './evaluation';
export * from './transaction-context';
export * from './type-guards';
export * from './open-feature';
44 changes: 1 addition & 43 deletions packages/shared/src/open-feature.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,13 @@ import { isDefined } from './filter';
import { EvaluationLifeCycle, Hook } from './hooks';
import { DefaultLogger, Logger, ManageLogger, SafeLogger } from './logger';
import { CommonProvider, ProviderMetadata, ProviderStatus } from './provider';
import {
ManageTransactionContextPropagator,
NOOP_TRANSACTION_CONTEXT_PROPAGATOR,
TransactionContext,
TransactionContextPropagator,
} from './transaction-context';
import { objectOrUndefined, stringOrUndefined } from './type-guards';
import { Paradigm } from './types';

export abstract class OpenFeatureCommonAPI<P extends CommonProvider = CommonProvider>
implements
Eventing,
EvaluationLifeCycle<OpenFeatureCommonAPI<P>>,
ManageLogger<OpenFeatureCommonAPI<P>>,
ManageTransactionContextPropagator<OpenFeatureCommonAPI<P>>
implements Eventing, EvaluationLifeCycle<OpenFeatureCommonAPI<P>>, ManageLogger<OpenFeatureCommonAPI<P>>
{
protected _hooks: Hook[] = [];
protected _transactionContextPropagator: TransactionContextPropagator = NOOP_TRANSACTION_CONTEXT_PROPAGATOR;
protected _context: EvaluationContext = {};
protected _logger: Logger = new DefaultLogger();

Expand Down Expand Up @@ -350,35 +339,4 @@ export abstract class OpenFeatureCommonAPI<P extends CommonProvider = CommonProv
this._logger.error(`Error during shutdown of provider ${provider.metadata.name}: ${err}`);
this._logger.error((err as Error)?.stack);
}

setTransactionContextPropagator(transactionContextPropagator: TransactionContextPropagator): OpenFeatureCommonAPI<P> {
const baseMessage = 'Invalid TransactionContextPropagator, will not be set: ';
if (typeof transactionContextPropagator?.getTransactionContext !== 'function') {
this._logger.error(`${baseMessage}: getTransactionContext is not a function.`);
} else if (typeof transactionContextPropagator?.setTransactionContext !== 'function') {
this._logger.error(`${baseMessage}: setTransactionContext is not a function.`);
} else {
this._transactionContextPropagator = transactionContextPropagator;
}
return this;
}

setTransactionContext<R>(
transactionContext: TransactionContext,
callback: (...args: unknown[]) => R,
...args: unknown[]
): void {
this._transactionContextPropagator.setTransactionContext(transactionContext, callback, ...args);
}

getTransactionContext(): TransactionContext {
try {
return this._transactionContextPropagator.getTransactionContext();
} catch (err: unknown) {
const error = err as Error | undefined;
this._logger.error(`Error getting transaction context: ${error?.message}, returning empty context.`);
this._logger.error(error?.stack);
return {};
}
}
}
4 changes: 3 additions & 1 deletion packages/shared/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,9 @@
},
"include": [
"./src/**/*"
],
,
"../server/src/transaction-context"
],
"exclude": [
"node_modules",
"**/*.test.js"
Expand Down

0 comments on commit 2cdf175

Please sign in to comment.