Skip to content

Commit 90b55d7

Browse files
committed
update
1 parent db3f9b1 commit 90b55d7

File tree

4 files changed

+35
-20
lines changed

4 files changed

+35
-20
lines changed

lib/project_config/project_config_manager.ts

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@
1414
* limitations under the License.
1515
*/
1616
import { LoggerFacade } from '../modules/logging';
17-
import { sprintf } from '../utils/fns';
18-
19-
import { ERROR_MESSAGES } from '../utils/enums';
2017
import { createOptimizelyConfig } from '../core/optimizely_config';
2118
import { OptimizelyConfig } from '../shared_types';
2219
import { DatafileManager } from './datafile_manager';
@@ -44,8 +41,8 @@ export interface ProjectConfigManager extends Service {
4441

4542
/**
4643
* ProjectConfigManager provides project config objects via its methods
47-
* getConfig and onUpdate. It uses a DatafileManager to fetch datafiles. It is
48-
* responsible for parsing and validating datafiles, and converting datafile
44+
* getConfig and onUpdate. It uses a DatafileManager to fetch datafile if provided.
45+
* It is responsible for parsing and validating datafiles, and converting datafile
4946
* string into project config objects.
5047
* @param {ProjectConfigManagerConfig} config
5148
*/
@@ -87,6 +84,10 @@ export class ProjectConfigManagerImpl extends BaseService implements ProjectConf
8784
}
8885

8986
this.datafileManager?.start();
87+
88+
// This handles the case where the datafile manager starts successfully. The
89+
// datafile manager will only start successfully when it has downloaded a datafile,
90+
// an will fire an onUpdate event.
9091
this.datafileManager?.onUpdate(this.handleNewDatafile.bind(this));
9192

9293
// If the datafile manager runs successfully, it will emit a onUpdate event. We can
@@ -105,20 +106,14 @@ export class ProjectConfigManagerImpl extends BaseService implements ProjectConf
105106
this.stopPromise.reject(error);
106107
}
107108

108-
/**
109-
* Respond to datafile manager's onRunning promise becoming rejected.
110-
* When DatafileManager's onReady promise is rejected, if a datafile was not provided and therefore
111-
* the projectConfigManager is still in New state, there is no possibility
112-
* of obtaining a datafile. In this case, ProjectConfigManager's ready promise
113-
* is fulfilled with an unsuccessful result.
114-
*/
115109
private handleDatafileManagerError(err: Error): void {
116110
// TODO: replace message with imported constants
117111
this.logger?.error('datafile manager failed to start', err);
118112

119113
// If datafile manager onRunning() promise is rejected, and the project config manager
120-
// is still in starting state, that means a datafile was not provided or was invalid.
121-
// In this case, we cannot recover and must reject the start promise.
114+
// is still in starting state, that means a datafile was not provided in cofig or was invalid,
115+
// otherwise the state would have already been set to running synchronously.
116+
// In this case, we cannot recover.
122117
if (this.isStarting()) {
123118
this.handleInitError(err);
124119
}
@@ -127,8 +122,9 @@ export class ProjectConfigManagerImpl extends BaseService implements ProjectConf
127122
/**
128123
* Handle new datafile by attemping to create a new Project Config object. If successful and
129124
* the new config object's revision is newer than the current one, sets/updates the project config
130-
* and optimizely config object instance variables and returns null for the error. If unsuccessful,
131-
* the project config and optimizely config objects will not be updated, and the error is returned.
125+
* and emits onUpdate event. If unsuccessful,
126+
* the project config and optimizely config objects will not be updated. If the error
127+
* is fatal, handleInitError will be called.
132128
*/
133129
private handleNewDatafile(newDatafile: string | object, fromConfig = false): void {
134130
if (this.isDone()) {
@@ -193,9 +189,6 @@ export class ProjectConfigManagerImpl extends BaseService implements ProjectConf
193189
return this.eventEmitter.on('update', listener);
194190
}
195191

196-
/**
197-
* Stop the internal datafile manager and remove all update listeners
198-
*/
199192
stop(): void {
200193
if (this.isDone()) {
201194
return;

lib/service.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,14 @@ export enum ServiceState {
3535
export interface Service {
3636
getState(): ServiceState;
3737
start(): void;
38+
// onRunning will reject if the service fails to start
39+
// or stopped before it could start.
40+
// It will resolve if the service is starts successfully.
3841
onRunning(): Promise<void>;
3942
stop(): void;
43+
// onTerminated will reject if the service enters a failed state
44+
// either by failing to start or stop.
45+
// It will resolve if the service is stopped successfully.
4046
onTerminated(): Promise<void>;
4147
}
4248

lib/utils/repeater/repeater.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,19 @@
1717
import { AsyncTransformer } from "../type";
1818
import { scheduleMicrotask } from "../microtask";
1919

20+
// A repeater will invoke the task repeatedly. The time at which the task is invoked
21+
// is determined by the implementation.
22+
// The task is a function that takes a number as an argument and returns a promise.
23+
// The number argument is the number of times the task previously failed consecutively.
24+
// If the retuned promise resolves, the repeater will assume the task succeeded,
25+
// and will reset the failure count. If the promise is rejected, the repeater will
26+
// assume the task failed and will increase the current consecutive failure count.
2027
export interface Repeater {
28+
// If immediateExecution is true, the first exection of
29+
// the task will be immediate but asynchronous.
2130
start(immediateExecution?: boolean): void;
2231
stop(): void;
32+
reset(): void;
2333
setTask(task: AsyncTransformer<number, void>): void;
2434
}
2535

@@ -52,6 +62,12 @@ export class ExponentialBackoff implements BackoffController {
5262
}
5363
}
5464

65+
// IntervalRepeater is a Repeater that invokes the task at a fixed interval
66+
// after the completion of the previous task invocation. If a backoff controller
67+
// is provided, the repeater will use the backoff controller to determine the
68+
// time between invocations after a failure instead. It will reset the backoffController
69+
// on success.
70+
5571
export class IntervalRepeater implements Repeater {
5672
private timeoutId?: NodeJS.Timeout;
5773
private task?: AsyncTransformer<number, void>;

vitest.config.mts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export default defineConfig({
2020
test: {
2121
onConsoleLog: () => true,
2222
environment: 'happy-dom',
23-
include: ['**/project_config_manager.spec.ts'],
23+
include: ['**/*.spec.ts'],
2424
typecheck: {
2525
tsconfig: 'tsconfig.spec.json',
2626
},

0 commit comments

Comments
 (0)