Skip to content

Commit 6d0a08b

Browse files
committed
Fixing review comments.
1 parent eeaa3d1 commit 6d0a08b

File tree

7 files changed

+45
-66
lines changed

7 files changed

+45
-66
lines changed

packages/sdk/browser/src/platform/DefaultBrowserEventSource.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import {
2+
DefaultBackoff,
23
EventListener,
34
EventName,
45
EventSourceInitDict,
56
HttpErrorResponse,
67
EventSource as LDEventSource,
78
} from '@launchdarkly/js-client-sdk-common';
8-
import { DefaultBackoff } from '@launchdarkly/js-sdk-common';
99

1010
/**
1111
* Implementation Notes:

packages/shared/common/__tests__/datasource/Backoff.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import DefaultBackoff from '../../src/datasource/Backoff';
1+
import { DefaultBackoff } from '../../src/datasource/Backoff';
22

33
const noJitter = (): number => 0;
44
const maxJitter = (): number => 1;

packages/shared/common/__tests__/subsystem/DataSystem/CompositeDataSource.test.ts

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import {
1111
InitializerFactory,
1212
SynchronizerFactory,
1313
} from '../../../src/api/subsystem/DataSystem/DataSource';
14-
import DefaultBackoff, { Backoff } from '../../../src/datasource/Backoff';
14+
import { Backoff } from '../../../src/datasource/Backoff';
1515

1616
function makeInitializerFactory(internal: DataSystemInitializer): InitializerFactory {
1717
return {
@@ -29,29 +29,29 @@ function makeTestTransitionConditions(): TransitionConditions {
2929
return {
3030
[DataSourceState.Initializing]: {
3131
durationMS: 0,
32-
transition: Transition.Fallback,
32+
transition: 'fallback',
3333
},
3434
[DataSourceState.Interrupted]: {
3535
durationMS: 0,
36-
transition: Transition.Fallback,
36+
transition: 'fallback',
3737
},
3838
[DataSourceState.Closed]: {
3939
durationMS: 0,
40-
transition: Transition.Fallback,
40+
transition: 'fallback',
4141
},
4242
[DataSourceState.Valid]: {
4343
durationMS: 0,
44-
transition: Transition.Fallback,
44+
transition: 'fallback',
4545
},
4646
};
4747
}
4848

4949
function makeZeroBackoff(): Backoff {
5050
return {
51-
success(_timeStampMs) {
51+
success() {
5252
return 0;
5353
},
54-
fail(_timeStampMs) {
54+
fail() {
5555
return 0;
5656
},
5757
};
@@ -323,9 +323,7 @@ it('it can be stopped when in thrashing synchronizer fallback loop', async () =>
323323
expect(mockInitializer1.run).toHaveBeenCalled();
324324
expect(mockSynchronizer1.run).toHaveBeenCalled();
325325
expect(dataCallback).toHaveBeenNthCalledWith(1, true, { key: 'init1' });
326-
console.log(`About to call stop on composite source.`);
327326
underTest.stop();
328-
console.log(`Got past stop`);
329327

330328
// wait for stop to take effect before checking status is closed
331329
await new Promise((f) => {
@@ -382,7 +380,6 @@ it('it can be stopped and restarted', async () => {
382380
await new Promise<void>((resolve) => {
383381
callback1 = jest.fn((_: boolean, data: Data) => {
384382
if (data === mockSynchronizer1Data) {
385-
console.log(`About to call stop`);
386383
underTest.stop();
387384
resolve();
388385
}

packages/shared/common/src/api/subsystem/DataSystem/CallbackHandler.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,21 @@ export class CallbackHandler {
1717
this._disabled = true;
1818
}
1919

20-
dataHanlder = async (basis: boolean, data: Data) => {
20+
async dataHanlder(basis: boolean, data: Data) {
2121
if (this._disabled) {
2222
return;
2323
}
2424

2525
// TODO: SDK-1044 track selector for future synchronizer to use
2626
// report data up
2727
this._dataCallback(basis, data);
28-
};
28+
}
2929

30-
statusHandler = async (status: DataSourceState, err?: any) => {
30+
async statusHandler(status: DataSourceState, err?: any) {
3131
if (this._disabled) {
3232
return;
3333
}
3434

3535
this._statusCallback(status, err);
36-
};
36+
}
3737
}

packages/shared/common/src/api/subsystem/DataSystem/CompositeDataSource.ts

Lines changed: 27 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -9,34 +9,16 @@ import {
99
SynchronizerFactory,
1010
} from './DataSource';
1111

12+
// TODO: SDK-858, specify these constants when CompositeDataSource is used.
13+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
14+
const DEFAULT_FALLBACK_TIME_MS = 2 * 60 * 1000;
15+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
16+
const DEFAULT_RECOVERY_TIME_MS = 5 * 60 * 1000;
17+
1218
/**
1319
* Represents a transition between data sources.
1420
*/
15-
export enum Transition {
16-
/**
17-
* A no-op transition.
18-
*/
19-
None,
20-
/**
21-
* Transition from current data source to the first synchronizer.
22-
*/
23-
SwitchToSync,
24-
25-
/**
26-
* Transition to the next data source of the same kind.
27-
*/
28-
Fallback,
29-
30-
/**
31-
* Transition to the first data source of the same kind.
32-
*/
33-
Recover,
34-
35-
/**
36-
* Transition to idle and reset
37-
*/
38-
Stop,
39-
}
21+
export type Transition = 'none' | 'switchToSync' | 'fallback' | 'recover' | 'stop';
4022

4123
/**
4224
* Given a {@link DataSourceState}, how long to wait before transitioning.
@@ -57,8 +39,6 @@ interface TransitionRequest {
5739
export class CompositeDataSource implements DataSource {
5840
// TODO: SDK-856 async notification if initializer takes too long
5941
// TODO: SDK-1044 utilize selector from initializers
60-
private readonly _defaultFallbackTimeMs = 2 * 60 * 1000;
61-
private readonly _defaultRecoveryTimeMs = 5 * 60 * 1000;
6242

6343
private _initPhaseActive: boolean = true;
6444
private _currentPosition: number = 0;
@@ -77,8 +57,8 @@ export class CompositeDataSource implements DataSource {
7757
private readonly _transitionConditions: TransitionConditions,
7858
private readonly _backoff: Backoff,
7959
) {
80-
this._externalTransitionPromise = new Promise<TransitionRequest>((tr) => {
81-
this._externalTransitionResolve = tr;
60+
this._externalTransitionPromise = new Promise<TransitionRequest>((resolveTransition) => {
61+
this._externalTransitionResolve = resolveTransition;
8262
});
8363
this._initPhaseActive = true;
8464
this._currentPosition = 0;
@@ -94,7 +74,7 @@ export class CompositeDataSource implements DataSource {
9474
}
9575
this._stopped = false;
9676

97-
let lastTransition: Transition = Transition.None;
77+
let lastTransition: Transition = 'none';
9878
// eslint-disable-next-line no-constant-condition
9979
while (true) {
10080
const currentDS: DataSource | undefined = this._pickDataSource(lastTransition);
@@ -108,13 +88,13 @@ export class CompositeDataSource implements DataSource {
10888
// this callback handler can be disabled and ensures only one transition request occurs
10989
const callbackHandler = new CallbackHandler(
11090
(basis: boolean, data: Data) => {
111-
this._backoff.success(Date.now());
91+
this._backoff.success();
11292
dataCallback(basis, data);
11393
if (basis && this._initPhaseActive) {
11494
// transition to sync if we get basis during init
11595
callbackHandler.disable();
11696
cancelScheduledTransition?.();
117-
transitionResolve({ transition: Transition.SwitchToSync });
97+
transitionResolve({ transition: 'switchToSync' });
11898
}
11999
},
120100
(state: DataSourceState, err?: any) => {
@@ -126,7 +106,7 @@ export class CompositeDataSource implements DataSource {
126106
callbackHandler.disable();
127107
statusCallback(DataSourceState.Interrupted, err); // underlying errors or closed states are masked as interrupted while we transition
128108
cancelScheduledTransition?.();
129-
transitionResolve({ transition: Transition.Fallback, err }); // unrecoverable error has occurred, so fallback
109+
transitionResolve({ transition: 'fallback', err }); // unrecoverable error has occurred, so fallback
130110
} else {
131111
statusCallback(state, null); // report the status upward
132112
if (state !== lastState) {
@@ -148,11 +128,14 @@ export class CompositeDataSource implements DataSource {
148128
}
149129
},
150130
);
151-
currentDS.run(callbackHandler.dataHanlder, callbackHandler.statusHandler);
131+
currentDS.run(
132+
(basis, data) => callbackHandler.dataHanlder(basis, data),
133+
(status, err) => callbackHandler.statusHandler(status, err),
134+
);
152135
} else {
153136
// we don't have a data source to use!
154137
transitionResolve({
155-
transition: Transition.Stop,
138+
transition: 'stop',
156139
err: {
157140
name: 'ExhaustedDataSources',
158141
message: `CompositeDataSource has exhausted all configured datasources (${this._initializers.length} initializers, ${this._synchronizers.length} synchronizers).`,
@@ -170,9 +153,9 @@ export class CompositeDataSource implements DataSource {
170153
// stop the underlying datasource before transitioning to next state
171154
currentDS?.stop();
172155

173-
if (transitionRequest.err && transitionRequest.transition !== Transition.Stop) {
156+
if (transitionRequest.err && transitionRequest.transition !== 'stop') {
174157
// if the transition was due to an error, throttle the transition
175-
const delay = this._backoff.fail(Date.now());
158+
const delay = this._backoff.fail();
176159
const delayedTransition = new Promise((resolve) => {
177160
setTimeout(resolve, delay);
178161
}).then(() => transitionRequest);
@@ -184,7 +167,7 @@ export class CompositeDataSource implements DataSource {
184167
]);
185168
}
186169

187-
if (transitionRequest.transition === Transition.Stop) {
170+
if (transitionRequest.transition === 'stop') {
188171
// exit the loop
189172
statusCallback(DataSourceState.Closed, transitionRequest.err);
190173
break;
@@ -198,7 +181,7 @@ export class CompositeDataSource implements DataSource {
198181
}
199182

200183
async stop() {
201-
this._externalTransitionResolve?.({ transition: Transition.Stop });
184+
this._externalTransitionResolve?.({ transition: 'stop' });
202185
}
203186

204187
private _reset() {
@@ -213,17 +196,17 @@ export class CompositeDataSource implements DataSource {
213196

214197
private _pickDataSource(transition: Transition | undefined): DataSource | undefined {
215198
switch (transition) {
216-
case Transition.SwitchToSync:
199+
case 'switchToSync':
217200
this._initPhaseActive = false; // one way toggle to false, unless this class is reset()
218201
this._currentPosition = 0;
219202
break;
220-
case Transition.Fallback:
203+
case 'fallback':
221204
this._currentPosition += 1;
222205
break;
223-
case Transition.Recover:
206+
case 'recover':
224207
this._currentPosition = 0;
225208
break;
226-
case Transition.None:
209+
case 'none':
227210
default:
228211
// don't do anything in this case
229212
break;
@@ -262,7 +245,7 @@ export class CompositeDataSource implements DataSource {
262245
const condition = this._transitionConditions[state];
263246

264247
// exclude recovery can happen for certain initializers/synchronizers (ex: the primary synchronizer shouldn't recover to itself)
265-
if (!condition || (excludeRecover && condition.transition === Transition.Recover)) {
248+
if (!condition || (excludeRecover && condition.transition === 'recover')) {
266249
return undefined;
267250
}
268251

packages/shared/common/src/api/subsystem/DataSystem/DataSource.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ export enum DataSourceState {
1111
export interface DataSource {
1212
/**
1313
* May be called any number of times, if already started, has no effect
14-
* @param cb may be invoked many times
15-
* @returns
14+
* @param dataCallback that will be called when data arrives, may be called multiple times.
15+
* @param statusCallback that will be called when data source state changes or an unrecoverable error
16+
* has been encountered.
1617
*/
1718
run(
1819
dataCallback: (basis: boolean, data: Data) => void,
@@ -21,8 +22,6 @@ export interface DataSource {
2122

2223
/**
2324
* May be called any number of times, if already stopped, has no effect.
24-
* @param cb
25-
* @returns
2625
*/
2726
stop(): void;
2827
}

packages/shared/common/src/datasource/Backoff.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ const MAX_RETRY_DELAY = 30 * 1000; // Maximum retry delay 30 seconds.
22
const JITTER_RATIO = 0.5; // Delay should be 50%-100% of calculated time.
33

44
export interface Backoff {
5-
success(timeStampMs: number): void;
6-
fail(timeStampMs: number): number;
5+
success(): void;
6+
fail(): number;
77
}
88

99
/**

0 commit comments

Comments
 (0)