|
1 | 1 | import { getDeviceId } from "@mongodb-js/device-id"; |
2 | | -import nodeMachineId from "node-machine-id"; |
| 2 | +import * as nodeMachineId from "node-machine-id"; |
3 | 3 | import type { LoggerBase } from "../common/logger.js"; |
4 | 4 | import { LogId } from "../common/logger.js"; |
5 | 5 |
|
6 | 6 | export const DEVICE_ID_TIMEOUT = 3000; |
7 | 7 |
|
8 | 8 | export class DeviceId { |
9 | | - private deviceId: string | undefined = undefined; |
10 | | - private deviceIdPromise: Promise<string> | undefined = undefined; |
11 | | - private abortController: AbortController | undefined = undefined; |
| 9 | + private static readonly UnknownDeviceId = Promise.resolve("unknown"); |
| 10 | + |
| 11 | + private deviceIdPromise: Promise<string>; |
| 12 | + private abortController: AbortController; |
12 | 13 | private logger: LoggerBase; |
13 | 14 | private readonly getMachineId: () => Promise<string>; |
14 | 15 | private timeout: number; |
15 | | - private static instance: DeviceId | undefined = undefined; |
16 | 16 |
|
17 | 17 | private constructor(logger: LoggerBase, timeout: number = DEVICE_ID_TIMEOUT) { |
18 | 18 | this.logger = logger; |
19 | 19 | this.timeout = timeout; |
20 | 20 | this.getMachineId = (): Promise<string> => nodeMachineId.machineId(true); |
| 21 | + this.abortController = new AbortController(); |
| 22 | + |
| 23 | + this.deviceIdPromise = DeviceId.UnknownDeviceId; |
21 | 24 | } |
22 | 25 |
|
23 | | - public static create(logger: LoggerBase, timeout?: number): DeviceId { |
24 | | - if (this.instance) { |
25 | | - throw new Error("DeviceId instance already exists, use get() to retrieve the device ID"); |
26 | | - } |
| 26 | + private initialize(): void { |
| 27 | + this.deviceIdPromise = getDeviceId({ |
| 28 | + getMachineId: this.getMachineId, |
| 29 | + onError: (reason, error) => { |
| 30 | + this.handleDeviceIdError(reason, String(error)); |
| 31 | + }, |
| 32 | + timeout: this.timeout, |
| 33 | + abortSignal: this.abortController.signal, |
| 34 | + }); |
| 35 | + } |
27 | 36 |
|
| 37 | + public static create(logger: LoggerBase, timeout?: number): DeviceId { |
28 | 38 | const instance = new DeviceId(logger, timeout ?? DEVICE_ID_TIMEOUT); |
29 | | - instance.setup(); |
30 | | - |
31 | | - this.instance = instance; |
| 39 | + instance.initialize(); |
32 | 40 |
|
33 | 41 | return instance; |
34 | 42 | } |
35 | 43 |
|
36 | | - private setup(): void { |
37 | | - this.deviceIdPromise = this.calculateDeviceId(); |
38 | | - } |
39 | | - |
40 | 44 | /** |
41 | 45 | * Closes the device ID calculation promise and abort controller. |
42 | 46 | */ |
43 | 47 | public close(): void { |
44 | | - if (this.abortController) { |
45 | | - this.abortController.abort(); |
46 | | - this.abortController = undefined; |
47 | | - } |
48 | | - |
49 | | - this.deviceId = undefined; |
50 | | - this.deviceIdPromise = undefined; |
51 | | - DeviceId.instance = undefined; |
| 48 | + this.abortController.abort(); |
52 | 49 | } |
53 | 50 |
|
54 | 51 | /** |
55 | 52 | * Gets the device ID, waiting for the calculation to complete if necessary. |
56 | 53 | * @returns Promise that resolves to the device ID string |
57 | 54 | */ |
58 | 55 | public get(): Promise<string> { |
59 | | - if (this.deviceId) { |
60 | | - return Promise.resolve(this.deviceId); |
61 | | - } |
62 | | - |
63 | | - if (this.deviceIdPromise) { |
64 | | - return this.deviceIdPromise; |
65 | | - } |
66 | | - |
67 | | - return this.calculateDeviceId(); |
68 | | - } |
69 | | - |
70 | | - /** |
71 | | - * Internal method that performs the actual device ID calculation. |
72 | | - */ |
73 | | - private async calculateDeviceId(): Promise<string> { |
74 | | - if (!this.abortController) { |
75 | | - this.abortController = new AbortController(); |
76 | | - } |
77 | | - |
78 | | - this.deviceIdPromise = getDeviceId({ |
79 | | - getMachineId: this.getMachineId, |
80 | | - onError: (reason, error) => { |
81 | | - this.handleDeviceIdError(reason, String(error)); |
82 | | - }, |
83 | | - timeout: this.timeout, |
84 | | - abortSignal: this.abortController.signal, |
85 | | - }); |
86 | | - |
87 | 56 | return this.deviceIdPromise; |
88 | 57 | } |
89 | 58 |
|
90 | 59 | private handleDeviceIdError(reason: string, error: string): void { |
91 | | - this.deviceIdPromise = Promise.resolve("unknown"); |
| 60 | + this.deviceIdPromise = DeviceId.UnknownDeviceId; |
92 | 61 |
|
93 | 62 | switch (reason) { |
94 | 63 | case "resolutionError": |
|
0 commit comments