@nsshunt/stsappframework 3.1.161 → 3.1.163

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.
Files changed (44) hide show
  1. package/dist/testertesting/app.js +39 -5
  2. package/dist/testertesting/app.js.map +1 -1
  3. package/dist/testertesting/commonTypes.js +30 -1
  4. package/dist/testertesting/commonTypes.js.map +1 -1
  5. package/dist/testertesting/telemetryProcessor.js +114 -0
  6. package/dist/testertesting/telemetryProcessor.js.map +1 -0
  7. package/dist/testertesting/testCase01.js +84 -0
  8. package/dist/testertesting/testCase01.js.map +1 -0
  9. package/dist/testertesting/workerInstance.js +107 -18
  10. package/dist/testertesting/workerInstance.js.map +1 -1
  11. package/dist/testertesting/workerManager.js +94 -118
  12. package/dist/testertesting/workerManager.js.map +1 -1
  13. package/dist/testertesting/workerPrimaryTestRunner01.js +5 -5
  14. package/dist/testertesting/workerPrimaryTestRunner01.js.map +1 -1
  15. package/dist/testertesting/workerWorkerTestRunner01.js +39 -14
  16. package/dist/testertesting/workerWorkerTestRunner01.js.map +1 -1
  17. package/package.json +1 -1
  18. package/src/testertesting/app.ts +50 -10
  19. package/src/testertesting/commonTypes.ts +172 -0
  20. package/src/testertesting/telemetryProcessor.ts +128 -0
  21. package/src/testertesting/testCase01.ts +107 -0
  22. package/src/testertesting/workerInstance.ts +128 -24
  23. package/src/testertesting/workerManager.ts +109 -141
  24. package/src/testertesting/workerPrimaryTestRunner01.ts +1 -1
  25. package/src/testertesting/workerWorkerTestRunner01.ts +24 -2
  26. package/types/testertesting/commonTypes.d.ts +155 -1
  27. package/types/testertesting/commonTypes.d.ts.map +1 -1
  28. package/types/testertesting/telemetryProcessor.d.ts +6 -0
  29. package/types/testertesting/telemetryProcessor.d.ts.map +1 -0
  30. package/types/testertesting/testCase01.d.ts +13 -0
  31. package/types/testertesting/testCase01.d.ts.map +1 -0
  32. package/types/testertesting/workerInstance.d.ts +9 -2
  33. package/types/testertesting/workerInstance.d.ts.map +1 -1
  34. package/types/testertesting/workerManager.d.ts +3 -1
  35. package/types/testertesting/workerManager.d.ts.map +1 -1
  36. package/types/testertesting/workerPrimaryTestRunner01.d.ts +1 -1
  37. package/types/testertesting/workerPrimaryTestRunner01.d.ts.map +1 -1
  38. package/types/testertesting/workerWorkerTestRunner01.d.ts +5 -1
  39. package/types/testertesting/workerWorkerTestRunner01.d.ts.map +1 -1
  40. package/dist/testertesting/stsTestWorkerDefinitions.js +0 -34
  41. package/dist/testertesting/stsTestWorkerDefinitions.js.map +0 -1
  42. package/src/testertesting/stsTestWorkerDefinitions.ts +0 -150
  43. package/types/testertesting/stsTestWorkerDefinitions.d.ts +0 -124
  44. package/types/testertesting/stsTestWorkerDefinitions.d.ts.map +0 -1
@@ -1,8 +1,8 @@
1
1
  /* eslint @typescript-eslint/no-explicit-any: 0, @typescript-eslint/no-unused-vars: 0 */ // --> OFF
2
2
  import cluster from 'cluster';
3
- import { Worker, MessageChannel } from 'worker_threads';
3
+ import { Worker } from 'worker_threads';
4
4
 
5
- import { IWorkerFactory, IWorkerOptions, IPrimaryWorker, IRunnerOptions } from './stsTestWorkerDefinitions'
5
+ import { IWorkerFactory, IWorkerOptions, IPrimaryWorker, IRunnerOptions } from './commonTypes'
6
6
 
7
7
  import { WorkerPrimaryTestRunner01 } from './workerPrimaryTestRunner01'
8
8
  import { STSWorkerManager } from './workerManager';
@@ -15,11 +15,14 @@ import { IContextBase, AgentInstrumentController, IPublishInstrumentControllerOp
15
15
  InstrumentDefinitions, InstrumentLogOptions, InstrumentGaugeOptions, PublishTransportRESTServer,
16
16
  TransportType, IPublishTransportRESTServerOptions } from '@nsshunt/stsobservability'
17
17
 
18
- import { ModelDelimeter, type ISTSLogger, defaultLogger } from '@nsshunt/stsutils'
18
+ import { ModelDelimeter, type ISTSLogger, defaultLogger, JSONObject } from '@nsshunt/stsutils'
19
19
 
20
20
  import { v4 as uuidv4 } from 'uuid';
21
21
 
22
22
  import { goptions } from '@nsshunt/stsconfig'
23
+ import { JsonWebTokenError } from 'jsonwebtoken';
24
+
25
+ import { IRunnerOptionsEx } from './testCase01'
23
26
 
24
27
  declare interface IAsyncRunnerContext extends IContextBase {
25
28
  id: string;
@@ -200,24 +203,61 @@ if (cluster.isPrimary) {
200
203
  }
201
204
  }
202
205
 
203
- const xx = async () => {
206
+ const PerformTesting = async () => {
204
207
  const wm = new STSWorkerManager(null, {
205
208
  workerFactory,
206
209
  publishInstrumentController: agentInstrumentController
207
210
  });
208
211
  const worker = await wm.AddWorker();
209
212
 
210
- const runnerOptions: IRunnerOptions = {
211
- iterations: 100000,
212
- sleepDuration: 250,
213
+ const runnerOptions: IRunnerOptionsEx = {
214
+ testType: 'TestCase01',
215
+ executionProfile: {
216
+ iterations: 50,
217
+ delayBetweenIterations: 250
218
+ },
219
+ sleepDuration: 0,
213
220
  messageMod: 1,
214
221
  logMessageMod: 1
215
- } as IRunnerOptions;
222
+ };
223
+
224
+ const runner1 = worker.AddRunner(runnerOptions);
225
+ runner1.on('Completed', () => {
226
+ console.log(chalk.rgb(10, 100, 250)(`Completed event handler for runner 1`));
227
+ });
216
228
 
217
- const runner = wm.AddRunnerToWorker(worker, runnerOptions);
229
+ worker.StartRunner(runner1);
230
+
231
+ const runner2 = wm.AddRunnerToWorker(worker, runnerOptions);
232
+ runner2.Start();
233
+ runner2.on('Completed', () => {
234
+ console.log(chalk.rgb(100, 10, 250)(`Completed event handler for runner 2`));
235
+ });
218
236
 
237
+ wm.AddRunnerToWorker(worker, runnerOptions).on('Completed', () => {
238
+ console.log(chalk.rgb(250, 100, 25)(`Completed event handler for runner 3`));
239
+ }).Start();
240
+
241
+ setTimeout(() => {
242
+ runner2.Pause();
243
+ setTimeout(() => {
244
+ runner2.Resume();
245
+ setTimeout(() => {
246
+ runner2.Reset();
247
+ setTimeout(() => {
248
+ runner2.Start();
249
+ setTimeout(() => {
250
+ runner2.Stop();
251
+ setTimeout(() => {
252
+ runner2.Terminate();
253
+ }, 2000);
254
+ }, 2000);
255
+ }, 100);
256
+ }, 2000);
257
+ }, 2000);
258
+ }, 2000);
219
259
  };
220
- xx();
260
+ PerformTesting();
221
261
 
222
262
 
223
263
  /*
@@ -1,3 +1,7 @@
1
+ import { Worker, MessagePort } from 'worker_threads';
2
+
3
+ import { PublishInstrumentController } from '@nsshunt/stsobservability'
4
+
1
5
  import { IContextBase } from '@nsshunt/stsobservability'
2
6
 
3
7
  export const URI_BASE_VUEUTILS: string = '/';
@@ -26,6 +30,13 @@ export enum eIWMessageCommands {
26
30
  MessagePortResponse = '__STS__MessagePortResponse',
27
31
  AddAsyncRunner = '__STS__AddAsyncRunner',
28
32
  StopAllAsyncRunners = '__STS__StopAllAsyncRunners',
33
+ StartRunner = '__STS__StartRunner',
34
+ StopRunner = '__STS__StopRunner',
35
+ PauseRunner = '__STS__PauseRunner',
36
+ ResumeRunner = '__STS__ResumeRunner',
37
+ ResetRunner = '__STS__ResetRunner',
38
+ ExecuteRunner = '__STS__ExecuteRunner',
39
+ Completed = '__STS__Completed'
29
40
  }
30
41
 
31
42
  /**
@@ -48,3 +59,164 @@ export interface IObservabilitySubscriberManagerOptions {
48
59
  instrumentManagerPort: string
49
60
  instrumentManagerAPIRoot: string
50
61
  }
62
+
63
+ export interface ISTSAgentWorkerMessagePort extends IIWMessagePayloadContentBase {
64
+ port: MessagePort
65
+ options: IWorkerOptions
66
+ }
67
+
68
+ export enum IRunnerState {
69
+ created = 'created',
70
+ running = 'running',
71
+ stopped = 'stopped',
72
+ paused = 'paused',
73
+ error = 'error',
74
+ }
75
+
76
+ export interface IRunnerTelemetry {
77
+ requestCount: number // requestCount
78
+ errorCount: number
79
+ retryCount: number
80
+ authenticationCount: number
81
+ authenticationErrorCount: number
82
+ authenticationRetryCount: number
83
+ velocity: number
84
+ coreCount: number
85
+ timer: number
86
+ duration: number
87
+ latency: number
88
+ activeRequestCount: number
89
+ message: string[]
90
+ childCount: number
91
+ rx: number
92
+ tx: number
93
+ }
94
+
95
+ export interface IRunner {
96
+ get id(): number
97
+ get asyncRunnerContext(): IAsyncRunnerContext
98
+ get options(): IRunnerOptions
99
+ set options(options: IRunnerOptions)
100
+ get instrumentData(): IRunnerTelemetry
101
+ set instrumentData(newRunnerTelemetry: IRunnerTelemetry)
102
+ }
103
+
104
+ export interface IRunnerEx extends IRunner {
105
+ publishInstrumentController: PublishInstrumentController
106
+ Start: () => Promise<boolean>
107
+ Pause: () => Promise<boolean>
108
+ Resume: () => Promise<boolean>
109
+ Stop: () => Promise<boolean>
110
+ Terminate: () => Promise<boolean>
111
+ Reset: () => Promise<boolean>
112
+ Execute: (iteration: number) => Promise<boolean> // Execute a single iteration for this test
113
+ on: (eventName: string, cb: () => void) => IRunnerEx
114
+ }
115
+
116
+ export interface IRunnerInstance {
117
+ Execute: (iteration: number) => Promise<boolean> // Execute a single iteration for this test
118
+ }
119
+
120
+ export enum IWorkerState {
121
+ starting = 'starting',
122
+ started = 'started',
123
+ stopped = 'stopped'
124
+ }
125
+
126
+
127
+ export interface IWorkerOptions {
128
+ hostName: string
129
+ agentId: string
130
+ userAgent: string
131
+ }
132
+
133
+ export type Runners = Record<string, IRunner>
134
+
135
+ export interface IWorker {
136
+ id: number
137
+ state: IWorkerState
138
+ primaryThreadWorkerOptions: IWorkerOptions
139
+ workerThreadWorkerOptions: IWorkerOptions
140
+ runners?: Runners // Will be created by utility helper
141
+ }
142
+
143
+ export type Workers = Record<string, IWorker>
144
+
145
+ export interface IPrimaryWorker {
146
+ ProcessMessageFromWorker(workerPort: MessagePort, publishMessagePayload: IIWMessagePayload): Promise<void>
147
+ }
148
+
149
+ export interface IExecutionProfile {
150
+ iterations: number
151
+ delayBetweenIterations: number
152
+ }
153
+
154
+ export interface IRunnerOptions {
155
+ testType: string
156
+ executionProfile: IExecutionProfile
157
+ }
158
+
159
+ export interface IRunnerEvent {
160
+ eventName: string
161
+ cb: () => void
162
+ }
163
+
164
+ export interface IWorkerEx extends IWorker {
165
+ worker: Worker
166
+ primaryWorker: IPrimaryWorker
167
+ runnersEx: Record<string, IRunnerEx>
168
+ runnersEvents: Record<string, IRunnerEvent[]>
169
+ GetRunner(id: string): IRunnerEx | null
170
+ AddRunner: (runnerOptions: IRunnerOptions) => IRunnerEx
171
+ StartRunner: (runner: IRunnerEx) => Promise<boolean>
172
+ StopRunner: (runner: IRunnerEx) => Promise<boolean>
173
+ PauseRunner: (runner: IRunnerEx) => Promise<boolean>
174
+ ResumeRunner: (runner: IRunnerEx) => Promise<boolean>
175
+ Stop: () => Promise<boolean>
176
+ }
177
+
178
+ export interface ISTSTestWorkerOptions {
179
+ messageMod: number
180
+ iterations: number
181
+ }
182
+
183
+ export interface ITelemetryStore {
184
+ workers: Workers
185
+ }
186
+
187
+ export interface ITestRunnerTelemetryPayload extends IIWMessagePayloadContentBase {
188
+ runner: IRunner
189
+ }
190
+
191
+ export interface IWorkerFactory {
192
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
193
+ createPrimaryThreadWorker: (app: any, options: IWorkerOptions) => IPrimaryWorker
194
+ createWorkerThreadWorker: () => Worker // | wt.Worker
195
+ get workerThreadWorkerOptions(): IWorkerOptions // These options will be passed as a message to the thread worker once setup
196
+ get primaryThreadWorkerOptions(): IWorkerOptions // These options will be passed as a message to the thread worker once setup
197
+ }
198
+
199
+ export interface IWorkerManagerOptions {
200
+ workerFactory: IWorkerFactory
201
+ publishInstrumentController: PublishInstrumentController
202
+ }
203
+
204
+ export const PublishMessageCommandsTestRunner = {
205
+ ...eIWMessageCommands,
206
+ GetAccessToken: '__GetAccessToken',
207
+ GetAccessTokenResponse: '__GetAccessTokenResponse',
208
+ GetDataFromPrimary: '__GetDataFromPrimary',
209
+ ExecuteRefreshToken: '__ExecuteRefreshToken',
210
+ ExecuteRefreshTokenResponse: '__ExecuteRefreshTokenResponse'
211
+ } as const
212
+
213
+ export type PublishMessageCommandsTestRunner = typeof PublishMessageCommandsTestRunner[keyof typeof PublishMessageCommandsTestRunner];
214
+
215
+ export interface IIWMessagePayloadContentBase {
216
+ messageId?: string;
217
+ }
218
+
219
+ export interface IIWMessagePayload {
220
+ command: IIWMessageCommand;
221
+ payload: IIWMessagePayloadContentBase;
222
+ }
@@ -0,0 +1,128 @@
1
+ import { PublishInstrumentController, InstrumentGaugeTelemetry, Gauge } from "@nsshunt/stsobservability";
2
+ import { IRunnerTelemetry } from "./commonTypes";
3
+
4
+ export class TelemetryProcessor {
5
+ ProcessTelemetry = (publishInstrumentController: PublishInstrumentController, telemetry: IRunnerTelemetry): boolean => {
6
+ let update = false;
7
+
8
+ if (telemetry.message) {
9
+ telemetry.message.forEach((message) => {
10
+ publishInstrumentController.LogEx(message);
11
+ });
12
+ update = true;
13
+ }
14
+
15
+ if (telemetry.requestCount) {
16
+ publishInstrumentController.UpdateInstrument(Gauge.REQUEST_COUNT_GAUGE, {
17
+ val: telemetry.requestCount
18
+ } as InstrumentGaugeTelemetry);
19
+ update = true;
20
+ }
21
+
22
+ if (telemetry.errorCount) {
23
+ publishInstrumentController.UpdateInstrument(Gauge.ERROR_COUNT_GAUGE, {
24
+ val: telemetry.errorCount
25
+ } as InstrumentGaugeTelemetry);
26
+ update = true;
27
+ }
28
+
29
+ if (telemetry.retryCount) {
30
+ publishInstrumentController.UpdateInstrument(Gauge.RETRY_COUNT_GAUGE, {
31
+ val: telemetry.retryCount
32
+ } as InstrumentGaugeTelemetry);
33
+ update = true;
34
+ }
35
+
36
+ if (telemetry.authenticationCount) {
37
+ publishInstrumentController.UpdateInstrument(Gauge.AUTHENTICATION_COUNT_GAUGE, {
38
+ val: telemetry.authenticationCount
39
+ } as InstrumentGaugeTelemetry);
40
+ update = true;
41
+ }
42
+
43
+ if (telemetry.authenticationErrorCount) {
44
+ publishInstrumentController.UpdateInstrument(Gauge.AUTHENTICATION_ERROR_COUNT_GAUGE, {
45
+ val: telemetry.authenticationCount
46
+ } as InstrumentGaugeTelemetry);
47
+ update = true;
48
+ }
49
+
50
+ if (telemetry.authenticationRetryCount) {
51
+ publishInstrumentController.UpdateInstrument(Gauge.AUTHENTICATION_RETRY_COUNT_GAUGE, {
52
+ val: telemetry.authenticationCount
53
+ } as InstrumentGaugeTelemetry);
54
+ update = true;
55
+ }
56
+
57
+ if (telemetry.coreCount) {
58
+ publishInstrumentController.UpdateInstrument(Gauge.CORE_COUNT_GAUGE, {
59
+ val: telemetry.coreCount
60
+ } as InstrumentGaugeTelemetry);
61
+ update = true;
62
+ }
63
+
64
+ if (telemetry.timer) {
65
+ publishInstrumentController.UpdateInstrument(Gauge.TIMER_GAUGE, {
66
+ val: telemetry.timer
67
+ } as InstrumentGaugeTelemetry);
68
+ update = true;
69
+ }
70
+
71
+ if (telemetry.activeRequestCount) {
72
+ publishInstrumentController.UpdateInstrument(Gauge.ACTIVE_REQUEST_GAUGE, {
73
+ val: telemetry.activeRequestCount
74
+ } as InstrumentGaugeTelemetry);
75
+ update = true;
76
+ }
77
+
78
+ if (telemetry.velocity) {
79
+ publishInstrumentController.UpdateInstrument(Gauge.VELOCITY_GAUGE, {
80
+ Inc: telemetry.velocity
81
+ } as InstrumentGaugeTelemetry);
82
+ update = true;
83
+ }
84
+
85
+ if (telemetry.duration) {
86
+ publishInstrumentController.UpdateInstrument(Gauge.DURATION_GAUGE, {
87
+ val: telemetry.duration
88
+ } as InstrumentGaugeTelemetry);
89
+ publishInstrumentController.UpdateInstrument(Gauge.DURATION_HISTOGRAM_GAUGE, {
90
+ val: telemetry.duration
91
+ } as InstrumentGaugeTelemetry);
92
+ update = true;
93
+ }
94
+
95
+ if (telemetry.latency) {
96
+ publishInstrumentController.UpdateInstrument(Gauge.LATENCY_GAUGE, {
97
+ val: telemetry.latency
98
+ } as InstrumentGaugeTelemetry);
99
+ publishInstrumentController.UpdateInstrument(Gauge.LATENCY_HISTOGRAM_GAUGE, {
100
+ val: telemetry.latency
101
+ } as InstrumentGaugeTelemetry);
102
+ update = true;
103
+ }
104
+
105
+ if (telemetry.childCount) {
106
+ publishInstrumentController.UpdateInstrument(Gauge.CHILD_COUNT, {
107
+ val: telemetry.childCount
108
+ } as InstrumentGaugeTelemetry);
109
+ update = true;
110
+ }
111
+
112
+ if (telemetry.rx) {
113
+ publishInstrumentController.UpdateInstrument(Gauge.NETWORK_RX_GAUGE, {
114
+ Inc: telemetry.rx
115
+ } as InstrumentGaugeTelemetry);
116
+ update = true;
117
+ }
118
+
119
+ if (telemetry.tx) {
120
+ publishInstrumentController.UpdateInstrument(Gauge.NETWORK_TX_GAUGE, {
121
+ Inc: telemetry.tx
122
+ } as InstrumentGaugeTelemetry);
123
+ update = true;
124
+ }
125
+
126
+ return update;
127
+ }
128
+ }
@@ -0,0 +1,107 @@
1
+ import { IRunnerInstance, IRunnerOptions, IRunner } from './commonTypes'
2
+
3
+ import chalk from 'chalk';
4
+
5
+ import { WorkerInstance } from './workerInstance'
6
+
7
+ import { Sleep } from '@nsshunt/stsutils'
8
+
9
+ declare interface LogMessageData {
10
+ indent: number
11
+ adder: number
12
+ }
13
+
14
+ declare type LogMessageDataSet = Record<string, LogMessageData>;
15
+
16
+ export interface IRunnerOptionsEx extends IRunnerOptions {
17
+ sleepDuration: number
18
+ messageMod: number
19
+ logMessageMod: number
20
+ }
21
+
22
+ export class TestCase01 implements IRunnerInstance {
23
+ #runner: IRunner
24
+ #workerInstance: WorkerInstance;
25
+ #logMessageDataSet: LogMessageDataSet = { };
26
+
27
+ constructor(workerInstance: WorkerInstance, runner: IRunner) {
28
+ this.#workerInstance = workerInstance;
29
+ this.#runner = runner;
30
+ }
31
+
32
+ #GenLogMessage = (runner: IRunner, iteration: number) => {
33
+ if (!this.#logMessageDataSet[runner.id]) {
34
+ this.#logMessageDataSet[runner.id] = {
35
+ adder: 1,
36
+ indent: 0
37
+ }
38
+ }
39
+ const logMessageData = this.#logMessageDataSet[runner.id];
40
+
41
+ let message = `${' '.repeat(logMessageData.indent)}>> Hello World << ${iteration}`;
42
+ const colorCode = runner.asyncRunnerContext.asyncRunnerId % 4;
43
+ switch (colorCode) {
44
+ case 0:
45
+ message = chalk.green(`${message}`);
46
+ break;
47
+ case 1:
48
+ message = chalk.yellow(`${message}`);
49
+ break;
50
+ case 2:
51
+ message = chalk.magenta(`${message}`);
52
+ break;
53
+ case 3:
54
+ message = chalk.white(`${message}`);
55
+ break;
56
+ }
57
+
58
+ console.log(message);
59
+ runner.instrumentData.message.push(message);
60
+ logMessageData.indent += logMessageData.adder;
61
+ if (logMessageData.indent > 20) {
62
+ logMessageData.adder = -1;
63
+ } else if (logMessageData.indent === 0) {
64
+ logMessageData.adder = 1;
65
+ }
66
+ }
67
+
68
+ Execute = async (iteration: number): Promise<boolean> => {
69
+ //console.log(chalk.magenta(`Execute! [${iteration}]`));
70
+ //console.log(chalk.magenta(JSON.stringify(this.#runner)));
71
+
72
+ this.#runner.instrumentData.coreCount = 1;
73
+
74
+ const options = this.#runner.options as IRunnerOptionsEx;
75
+
76
+ await Sleep(options.sleepDuration);
77
+
78
+ //this.#runner.instrumentData.timer++;
79
+ this.#runner.instrumentData.requestCount++;
80
+ this.#runner.instrumentData.velocity = options.messageMod;
81
+
82
+ //runner.instrumentData.tx += 256;
83
+ //runner.instrumentData.rx += 6500;
84
+
85
+ if (this.#runner.instrumentData.requestCount % options.logMessageMod === 0) {
86
+ this.#GenLogMessage(this.#runner, iteration);
87
+ }
88
+
89
+ if (this.#runner.instrumentData.requestCount % options.messageMod === 0) {
90
+ this.#workerInstance.PostTelemetry(this.#runner);
91
+ this.#runner.instrumentData.message = [ ];
92
+ this.#runner.instrumentData.tx = 0;
93
+ this.#runner.instrumentData.rx = 0;
94
+ }
95
+ if (this.#runner.instrumentData.requestCount % 1000 === 0) {
96
+ const message = `Worker: [${this.#runner.asyncRunnerContext.threadId}], Runner: [${this.#runner.asyncRunnerContext.asyncRunnerId}] has completed: [${this.#runner.instrumentData.requestCount}] iterations of max: [${options.executionProfile.iterations}]`;
97
+ console.log(message);
98
+ this.#runner.instrumentData.message = [message]
99
+ this.#workerInstance.PostTelemetry(this.#runner);
100
+ this.#runner.instrumentData.message = [ ];
101
+ this.#runner.instrumentData.tx = 0;
102
+ this.#runner.instrumentData.rx = 0;
103
+ }
104
+
105
+ return true;
106
+ }
107
+ }