@twin.org/telemetry-service 0.9.1-next.3 → 0.9.1-next.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -57,7 +57,8 @@ export class MetricsCollectorService {
|
|
|
57
57
|
}
|
|
58
58
|
/**
|
|
59
59
|
* Start the service: register all producers and begin the polling cycle.
|
|
60
|
-
*
|
|
60
|
+
* The first collection tick fires immediately but does not block start() from returning.
|
|
61
|
+
* @returns A promise that resolves once producers are registered and the first tick is in flight.
|
|
61
62
|
*/
|
|
62
63
|
async start() {
|
|
63
64
|
if (this._running) {
|
|
@@ -69,17 +70,20 @@ export class MetricsCollectorService {
|
|
|
69
70
|
for (const producer of producers) {
|
|
70
71
|
await this._platformComponent.execute(async () => producer.register());
|
|
71
72
|
}
|
|
72
|
-
|
|
73
|
+
// Defer the first tick to the next event-loop turn so start() returns before any
|
|
74
|
+
// collection work begins, keeping engine boot unblocked.
|
|
75
|
+
this._timer = globalThis.setTimeout(async () => {
|
|
76
|
+
await this.tick();
|
|
77
|
+
}, 0);
|
|
73
78
|
}
|
|
74
79
|
/**
|
|
75
80
|
* Stop the service and cancel the pending timer.
|
|
76
81
|
* @returns A promise that resolves when the service has stopped.
|
|
77
82
|
*/
|
|
78
83
|
async stop() {
|
|
79
|
-
this._running
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
this._timer = undefined;
|
|
84
|
+
if (this._running) {
|
|
85
|
+
this._running = false;
|
|
86
|
+
this.stopTimer();
|
|
83
87
|
}
|
|
84
88
|
}
|
|
85
89
|
/**
|
|
@@ -106,18 +110,29 @@ export class MetricsCollectorService {
|
|
|
106
110
|
});
|
|
107
111
|
}
|
|
108
112
|
}
|
|
109
|
-
this.
|
|
113
|
+
this.startTimer();
|
|
110
114
|
}
|
|
111
115
|
/**
|
|
112
116
|
* Schedule the next tick after the configured interval.
|
|
113
117
|
* @internal
|
|
114
118
|
*/
|
|
115
|
-
|
|
119
|
+
startTimer() {
|
|
116
120
|
if (this._running) {
|
|
121
|
+
this.stopTimer();
|
|
117
122
|
this._timer = globalThis.setTimeout(async () => {
|
|
118
123
|
await this.tick();
|
|
119
124
|
}, this._intervalMs);
|
|
120
125
|
}
|
|
121
126
|
}
|
|
127
|
+
/**
|
|
128
|
+
* Stop the timer.
|
|
129
|
+
* @internal
|
|
130
|
+
*/
|
|
131
|
+
stopTimer() {
|
|
132
|
+
if (this._timer !== undefined) {
|
|
133
|
+
globalThis.clearTimeout(this._timer);
|
|
134
|
+
this._timer = undefined;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
122
137
|
}
|
|
123
138
|
//# sourceMappingURL=metricsCollectorService.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metricsCollectorService.js","sourceRoot":"","sources":["../../src/metricsCollectorService.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAG7D,OAAO,EAEN,sBAAsB,EACtB,MAAM,4BAA4B,CAAC;AAGpC;;GAEG;AACH,MAAM,OAAO,uBAAuB;IACnC;;OAEG;IACI,MAAM,CAAU,UAAU,6BAA6C;IAE9E;;;OAGG;IACc,iBAAiB,CAAqB;IAEvD;;;OAGG;IACc,kBAAkB,CAAqB;IAExD;;;OAGG;IACc,WAAW,CAAS;IAErC;;;OAGG;IACK,MAAM,CAAuD;IAErE;;;OAGG;IACK,QAAQ,CAAU;IAE1B;;;;OAIG;IACH,YAAY,OAAoD;QAC/D,IAAI,CAAC,iBAAiB,GAAG,gBAAgB,CAAC,WAAW,CACpD,OAAO,EAAE,oBAAoB,CAC7B,CAAC;QACF,IAAI,CAAC,kBAAkB,GAAG,gBAAgB,CAAC,GAAG,CAC7C,OAAO,EAAE,qBAAqB,IAAI,UAAU,CAC5C,CAAC;QAEF,MAAM,UAAU,GAAG,OAAO,EAAE,MAAM,EAAE,UAAU,IAAI,MAAM,CAAC;QACzD,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,UAAU,IAAI,CAAC,EAAE,CAAC;YACrD,MAAM,IAAI,UAAU,CAAC,oDAAoD,UAAU,EAAE,CAAC,CAAC;QACxF,CAAC;QACD,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC;QAC9B,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;IACvB,CAAC;IAED;;;OAGG;IACI,SAAS;QACf,OAAO,uBAAuB,CAAC,UAAU,CAAC;IAC3C,CAAC;IAED
|
|
1
|
+
{"version":3,"file":"metricsCollectorService.js","sourceRoot":"","sources":["../../src/metricsCollectorService.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2026 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { IPlatformComponent } from \"@twin.org/api-models\";\nimport { BaseError, ComponentFactory } from \"@twin.org/core\";\nimport type { ILoggingComponent } from \"@twin.org/logging-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport {\n\ttype IMetricsCollectorComponent,\n\tMetricsProducerFactory\n} from \"@twin.org/telemetry-models\";\nimport type { IMetricsCollectorServiceConstructorOptions } from \"./models/IMetricsCollectorServiceConstructorOptions.js\";\n\n/**\n * Collects metrics from registered producers at a fixed interval.\n */\nexport class MetricsCollectorService implements IMetricsCollectorComponent {\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<MetricsCollectorService>();\n\n\t/**\n\t * Resolved logging component for internal use.\n\t * @internal\n\t */\n\tprivate readonly _loggingComponent?: ILoggingComponent;\n\n\t/**\n\t * Platform component.\n\t * @internal\n\t */\n\tprivate readonly _platformComponent: IPlatformComponent;\n\n\t/**\n\t * Polling interval in milliseconds.\n\t * @internal\n\t */\n\tprivate readonly _intervalMs: number;\n\n\t/**\n\t * Pending scheduled tick handle.\n\t * @internal\n\t */\n\tprivate _timer: ReturnType<typeof globalThis.setTimeout> | undefined;\n\n\t/**\n\t * Whether the service is currently running.\n\t * @internal\n\t */\n\tprivate _running: boolean;\n\n\t/**\n\t * Create a new instance of MetricsCollectorService.\n\t * @param options The options for the service.\n\t * @throws {RangeError} If intervalMs is not a finite positive number.\n\t */\n\tconstructor(options?: IMetricsCollectorServiceConstructorOptions) {\n\t\tthis._loggingComponent = ComponentFactory.getIfExists<ILoggingComponent>(\n\t\t\toptions?.loggingComponentType\n\t\t);\n\t\tthis._platformComponent = ComponentFactory.get<IPlatformComponent>(\n\t\t\toptions?.platformComponentType ?? \"platform\"\n\t\t);\n\n\t\tconst intervalMs = options?.config?.intervalMs ?? 60_000;\n\t\tif (!Number.isFinite(intervalMs) || intervalMs <= 0) {\n\t\t\tthrow new RangeError(`intervalMs must be a finite positive number, got ${intervalMs}`);\n\t\t}\n\t\tthis._intervalMs = intervalMs;\n\t\tthis._running = false;\n\t}\n\n\t/**\n\t * Returns the class name of the component.\n\t * @returns The class name of the component.\n\t */\n\tpublic className(): string {\n\t\treturn MetricsCollectorService.CLASS_NAME;\n\t}\n\n\t/**\n\t * Start the service: register all producers and begin the polling cycle.\n\t * The first collection tick fires immediately but does not block start() from returning.\n\t * @returns A promise that resolves once producers are registered and the first tick is in flight.\n\t */\n\tpublic async start(): Promise<void> {\n\t\tif (this._running) {\n\t\t\treturn;\n\t\t}\n\t\tthis._running = true;\n\n\t\tconst names = MetricsProducerFactory.names();\n\t\tconst producers = names.map(name => MetricsProducerFactory.get(name));\n\n\t\tfor (const producer of producers) {\n\t\t\tawait this._platformComponent.execute(async () => producer.register());\n\t\t}\n\n\t\t// Defer the first tick to the next event-loop turn so start() returns before any\n\t\t// collection work begins, keeping engine boot unblocked.\n\t\tthis._timer = globalThis.setTimeout(async () => {\n\t\t\tawait this.tick();\n\t\t}, 0);\n\t}\n\n\t/**\n\t * Stop the service and cancel the pending timer.\n\t * @returns A promise that resolves when the service has stopped.\n\t */\n\tpublic async stop(): Promise<void> {\n\t\tif (this._running) {\n\t\t\tthis._running = false;\n\t\t\tthis.stopTimer();\n\t\t}\n\t}\n\n\t/**\n\t * One collection cycle across all registered producers.\n\t * Public so tests can drive it deterministically.\n\t * @returns A promise that resolves when all producers have been polled and the next tick scheduled.\n\t */\n\tpublic async tick(): Promise<void> {\n\t\tconst names = MetricsProducerFactory.names();\n\t\tconst producers = names.map(name => MetricsProducerFactory.get(name));\n\n\t\tfor (const producer of producers) {\n\t\t\ttry {\n\t\t\t\tawait this._platformComponent.execute(async () => producer.collect());\n\t\t\t} catch (err) {\n\t\t\t\tawait this._loggingComponent?.log({\n\t\t\t\t\tsource: MetricsCollectorService.CLASS_NAME,\n\t\t\t\t\tlevel: \"error\",\n\t\t\t\t\tmessage: \"producerCollectionFailed\",\n\t\t\t\t\tdata: {\n\t\t\t\t\t\tproducer: producer.className()\n\t\t\t\t\t},\n\t\t\t\t\terror: BaseError.fromError(err)\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tthis.startTimer();\n\t}\n\n\t/**\n\t * Schedule the next tick after the configured interval.\n\t * @internal\n\t */\n\tprivate startTimer(): void {\n\t\tif (this._running) {\n\t\t\tthis.stopTimer();\n\n\t\t\tthis._timer = globalThis.setTimeout(async () => {\n\t\t\t\tawait this.tick();\n\t\t\t}, this._intervalMs);\n\t\t}\n\t}\n\n\t/**\n\t * Stop the timer.\n\t * @internal\n\t */\n\tprivate stopTimer(): void {\n\t\tif (this._timer !== undefined) {\n\t\t\tglobalThis.clearTimeout(this._timer);\n\t\t\tthis._timer = undefined;\n\t\t}\n\t}\n}\n"]}
|
|
@@ -21,7 +21,8 @@ export declare class MetricsCollectorService implements IMetricsCollectorCompone
|
|
|
21
21
|
className(): string;
|
|
22
22
|
/**
|
|
23
23
|
* Start the service: register all producers and begin the polling cycle.
|
|
24
|
-
*
|
|
24
|
+
* The first collection tick fires immediately but does not block start() from returning.
|
|
25
|
+
* @returns A promise that resolves once producers are registered and the first tick is in flight.
|
|
25
26
|
*/
|
|
26
27
|
start(): Promise<void>;
|
|
27
28
|
/**
|
package/docs/changelog.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.9.1-next.5](https://github.com/iotaledger/twin-telemetry/compare/telemetry-service-v0.9.1-next.4...telemetry-service-v0.9.1-next.5) (2026-07-24)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* background initial tick ([#62](https://github.com/iotaledger/twin-telemetry/issues/62)) ([c9bf637](https://github.com/iotaledger/twin-telemetry/commit/c9bf6370faf7ebc254aaa675d94fe327317f0b21))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Dependencies
|
|
12
|
+
|
|
13
|
+
* The following workspace dependencies were updated
|
|
14
|
+
* dependencies
|
|
15
|
+
* @twin.org/telemetry-models bumped from 0.9.1-next.4 to 0.9.1-next.5
|
|
16
|
+
|
|
17
|
+
## [0.9.1-next.4](https://github.com/iotaledger/twin-telemetry/compare/telemetry-service-v0.9.1-next.3...telemetry-service-v0.9.1-next.4) (2026-07-02)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
* timer state machine ([761731e](https://github.com/iotaledger/twin-telemetry/commit/761731efe5a7f5b1b7b71e200afaa5dc0ded623c))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Dependencies
|
|
26
|
+
|
|
27
|
+
* The following workspace dependencies were updated
|
|
28
|
+
* dependencies
|
|
29
|
+
* @twin.org/telemetry-models bumped from 0.9.1-next.3 to 0.9.1-next.4
|
|
30
|
+
|
|
3
31
|
## [0.9.1-next.3](https://github.com/iotaledger/twin-telemetry/compare/telemetry-service-v0.9.1-next.2...telemetry-service-v0.9.1-next.3) (2026-06-30)
|
|
4
32
|
|
|
5
33
|
|
|
@@ -63,12 +63,13 @@ The class name of the component.
|
|
|
63
63
|
> **start**(): `Promise`\<`void`\>
|
|
64
64
|
|
|
65
65
|
Start the service: register all producers and begin the polling cycle.
|
|
66
|
+
The first collection tick fires immediately but does not block start() from returning.
|
|
66
67
|
|
|
67
68
|
#### Returns
|
|
68
69
|
|
|
69
70
|
`Promise`\<`void`\>
|
|
70
71
|
|
|
71
|
-
A promise that resolves
|
|
72
|
+
A promise that resolves once producers are registered and the first tick is in flight.
|
|
72
73
|
|
|
73
74
|
#### Implementation of
|
|
74
75
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@twin.org/telemetry-service",
|
|
3
|
-
"version": "0.9.1-next.
|
|
3
|
+
"version": "0.9.1-next.5",
|
|
4
4
|
"description": "Telemetry service implementation with REST entry points.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"license": "Apache-2.0",
|
|
12
12
|
"type": "module",
|
|
13
13
|
"engines": {
|
|
14
|
-
"node": ">=
|
|
14
|
+
"node": ">=24.0.0"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@twin.org/api-models": "next",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"@twin.org/entity": "next",
|
|
21
21
|
"@twin.org/logging-models": "next",
|
|
22
22
|
"@twin.org/nameof": "next",
|
|
23
|
-
"@twin.org/telemetry-models": "0.9.1-next.
|
|
23
|
+
"@twin.org/telemetry-models": "0.9.1-next.5",
|
|
24
24
|
"@twin.org/web": "next"
|
|
25
25
|
},
|
|
26
26
|
"main": "./dist/es/index.js",
|