Skip to content

Commit 5a864ce

Browse files
authored
Merge pull request #254 from Dexterp37/fix_dispatcher
Bug 1705720 - Ensure the dispatcher is always available
2 parents ef82912 + 8b97fcd commit 5a864ce

File tree

4 files changed

+49
-14
lines changed

4 files changed

+49
-14
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
[Full changelog](https://github.com/mozilla/glean.js/compare/v0.10.0...main)
44

5+
* [#254](https://github.com/mozilla/glean.js/pull/254): BUGFIX: Allow the usage of the Glean specific metrics API before Glean is initialized.
6+
57
# v0.10.0 (2021-04-20)
68

79
[Full changelog](https://github.com/mozilla/glean.js/compare/v0.9.2...v0.10.0)

glean/src/core/context.ts

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44

55
import type { DebugOptions } from "./debug_options";
6-
import type Dispatcher from "./dispatcher";
6+
import Dispatcher from "./dispatcher";
77
import type MetricsDatabase from "./metrics/database";
88
import type EventsDatabase from "./metrics/events_database";
99
import type PingsDatabase from "./pings/database";
@@ -23,21 +23,20 @@ import type PingsDatabase from "./pings/database";
2323
export class Context {
2424
private static _instance: Context;
2525

26-
private _dispatcher!: Dispatcher;
26+
private _dispatcher!: Dispatcher | null;
2727

2828
private _uploadEnabled!: boolean;
2929
private _metricsDatabase!: MetricsDatabase;
3030
private _eventsDatabase!: EventsDatabase;
3131
private _pingsDatabase!: PingsDatabase;
3232

3333
private _applicationId!: string;
34-
private _initialized!: boolean;
34+
private _initialized: boolean;
3535

3636
private _debugOptions!: DebugOptions;
3737

3838
private constructor() {
39-
// Intentionally empty, exclusively defined to mark the
40-
// constructor as private.
39+
this._initialized = false;
4140
}
4241

4342
static get instance(): Context {
@@ -48,7 +47,33 @@ export class Context {
4847
return Context._instance;
4948
}
5049

50+
/**
51+
* **Test-only API**
52+
*
53+
* Resets the Context to an uninitialized state.
54+
*/
55+
static async testUninitialize(): Promise<void> {
56+
// Clear the dispatcher queue and return the dispatcher back to an uninitialized state.
57+
if (Context.instance._dispatcher) {
58+
await Context.instance._dispatcher.testUninitialize();
59+
}
60+
61+
// Due to the test requirement of keeping storage in place,
62+
// we can't simply wipe out the full `Context` instance.
63+
// The closest thing we can do is making the dispatcher `null`.
64+
Context.instance._dispatcher = null;
65+
Context.initialized = false;
66+
}
67+
5168
static get dispatcher(): Dispatcher {
69+
// Create a dispatcher if one isn't available already.
70+
// This is required since the dispatcher may be used
71+
// earlier than Glean initialization, so we can't rely
72+
// on `Glean.initialize` to set it.
73+
if (!Context.instance._dispatcher) {
74+
Context.instance._dispatcher = new Dispatcher();
75+
}
76+
5277
return Context.instance._dispatcher;
5378
}
5479

glean/src/core/glean.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ import EventsDatabase from "./metrics/events_database.js";
1414
import UUIDMetricType from "./metrics/types/uuid.js";
1515
import DatetimeMetricType from "./metrics/types/datetime.js";
1616
import { DatetimeMetric } from "./metrics/types/datetime_metric.js";
17-
import Dispatcher from "./dispatcher.js";
1817
import CorePings from "./internal_pings.js";
1918
import { registerPluginToEvent, testResetEvents } from "./events/utils.js";
2019

@@ -51,10 +50,8 @@ class Glean {
5150
Use Glean.instance instead to access the Glean singleton.`);
5251
}
5352

54-
Context.dispatcher = new Dispatcher();
5553
this._coreMetrics = new CoreMetrics();
5654
this._corePings = new CorePings();
57-
Context.initialized = false;
5855
}
5956

6057
private static get instance(): Glean {
@@ -501,16 +498,11 @@ class Glean {
501498
*/
502499
static async testUninitialize(): Promise<void> {
503500
// Get back to an uninitialized state.
504-
Context.initialized = false;
501+
await Context.testUninitialize();
505502

506503
// Deregister all plugins
507504
testResetEvents();
508505

509-
// Clear the dispatcher queue and return the dispatcher back to an uninitialized state.
510-
if (Context.dispatcher) {
511-
await Context.dispatcher.testUninitialize();
512-
}
513-
514506
// Stop ongoing jobs and clear pending pings queue.
515507
if (Glean.pingUploader) {
516508
// The first time tests run, before Glean is initialized, we are

glean/tests/core/context.spec.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,20 @@ describe("Context", function() {
6868
assert.notStrictEqual(Context.pingsDatabase, undefined);
6969
assert.ok(Context.pingsDatabase instanceof PingsDatabase);
7070
});
71+
72+
it("the dispatcher is always available", async function () {
73+
const originalDispatcher = Context.dispatcher;
74+
assert.notStrictEqual(originalDispatcher, null);
75+
76+
await Context.testUninitialize();
77+
78+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
79+
// @ts-ignore
80+
assert.strictEqual(Context.instance._dispatcher, null);
81+
82+
// Trying to access the dispatcher will instantiate a new one.
83+
const newDispatcher = Context.instance;
84+
assert.notStrictEqual(newDispatcher, null);
85+
assert.notStrictEqual(newDispatcher, originalDispatcher);
86+
});
7187
});

0 commit comments

Comments
 (0)