Skip to content

Commit 7853884

Browse files
committed
Refactored event into a seperate example file
1 parent 9d10355 commit 7853884

4 files changed

Lines changed: 85 additions & 75 deletions

File tree

client.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ class Client {
182182
* codeMask: 0,
183183
* limit: 100,
184184
* offset: 0,
185-
* flags: 1 // Numeric flags as defined in your protocol
185+
* flags: 1
186186
* }
187187
* @returns {Promise<Array>} Resolves with an array of events.
188188
*/

event.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// event.js
22
global.WebSocket = require('ws');
33
const Client = require('./client');
4+
// NOTE: Event support is only on API version 4.0.0+
45

56
/**
67
* Recursively normalizes an object/value.

index.js

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -50,50 +50,11 @@ async function printDataPoints() {
5050
}
5151
}
5252

53-
// Print events retrieved within a time range corresponding to UTC 9:40.
54-
// In this example, we use a 5-minute window starting at UTC 9:40.
55-
async function printEvents() {
56-
try {
57-
// Specify the target time for events in UTC.
58-
// Adjust the date as needed; here we assume a specific date.
59-
const targetDate = new Date("2025-03-21T09:38:00Z");
60-
const targetTime = targetDate.getTime() / 1000;
61-
// Define a window of 5 minutes (300 seconds)
62-
const timeWindow = 5 * 60;
63-
64-
const eventQuery = {
65-
timeRangeBegin: targetTime,
66-
timeRangeEnd: targetTime + timeWindow,
67-
codeMask: 0,
68-
limit: 100,
69-
offset: 0,
70-
flags: 0,
71-
// Optionally, add senderConditions or dataConditions if desired.
72-
};
73-
74-
const events = await client.requestEvents(eventQuery);
75-
console.log("Events retrieved:");
76-
if (!events || events.length === 0) {
77-
console.log("No events found with the current query.");
78-
} else {
79-
events.forEach(evt => {
80-
console.log(`Timestamp: ${evt.timestampSec}`);
81-
console.log(` Code: ${evt.data && evt.data.Code ? evt.data.Code : "N/A"}`);
82-
console.log(` Source: ${evt.data && evt.data.Source ? evt.data.Source : "N/A"}`);
83-
console.log(` Text: ${evt.data && evt.data.Text ? evt.data.Text : "N/A"}`);
84-
console.log('--------------------');
85-
});
86-
}
87-
} catch (err) {
88-
console.error("Error retrieving events:", err);
89-
}
90-
}
9153

9254
async function main() {
9355
try {
9456
printLoggedNodes();
9557
await printDataPoints();
96-
await printEvents();
9758
} catch (error) {
9859
console.error("Error in main:", error);
9960
} finally {

test/testTimeSync.js

Lines changed: 83 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -12,67 +12,88 @@ global.WebSocket = class {
1212
}
1313
};
1414

15+
// --- Capture Request IDs for time sync vs. API calls ---
16+
// We override _getRequestId so that for each API call the first call is used for
17+
// the time sync update and the second call is used for the actual API request.
18+
let capturedTimeSyncRequestId = null;
19+
let capturedApiRequestId = null;
20+
const originalGetRequestId = Client.prototype._getRequestId;
21+
Client.prototype._getRequestId = function() {
22+
const id = originalGetRequestId.call(this);
23+
if (capturedTimeSyncRequestId === null) {
24+
capturedTimeSyncRequestId = id;
25+
} else if (capturedApiRequestId === null) {
26+
capturedApiRequestId = id;
27+
}
28+
return id;
29+
};
30+
1531
/**
1632
* Helper function to run an API method with time sync enabled and then disabled.
17-
* It forces an update (by setting lastTimeRequest to an old value) before each call.
18-
* The simulateResponse callback simulates the corresponding response by calling _parseMessage.
33+
* It forces a time update (by setting lastTimeRequest to an old value) before each call.
34+
* The simulateResponse callback simulates the corresponding responses by calling _parseMessage.
35+
* The callback receives two parameters: timeSyncRequestId and apiRequestId.
1936
*/
2037
async function runThrough(methodName, callFunc, simulateResponse) {
38+
// Reset captured IDs for this run.
39+
capturedTimeSyncRequestId = null;
40+
capturedApiRequestId = null;
41+
2142
console.log(`\n=== Running ${methodName} with time sync ENABLED ===`);
22-
// Force a time update by setting lastTimeRequest to an old value.
43+
// Force a time update.
2344
client.lastTimeRequest = Date.now() / 1000 - 20;
2445
// Call the API method.
2546
callFunc();
26-
// Simulate a response if needed.
27-
if (simulateResponse) simulateResponse();
28-
// Wait longer for the time sync update to complete.
47+
// Allow the _getRequestId calls to occur.
48+
await new Promise(resolve => setTimeout(resolve, 50));
49+
// Simulate two responses: first for the time sync update, then for the API response.
50+
if (simulateResponse) simulateResponse(capturedTimeSyncRequestId, capturedApiRequestId);
51+
// Wait for responses to be processed.
2952
await new Promise(resolve => setTimeout(resolve, 300));
3053
console.log(`${methodName} -> timeDiff: ${client.timeDiff.toFixed(6)} sec`);
3154

3255
// Now disable time sync.
33-
// Clear any pending time requests so they don't update timeDiff later.
3456
client.storedPromises = {};
3557
client.setEnableTimeSync(false);
3658
console.log(`\n=== Running ${methodName} with time sync DISABLED ===`);
3759
const previousTimeDiff = client.timeDiff;
3860
client.lastTimeRequest = Date.now() / 1000 - 20;
61+
// Reset captured IDs for the disabled run.
62+
capturedTimeSyncRequestId = null;
63+
capturedApiRequestId = null;
3964
callFunc();
40-
// When time sync is disabled, do NOT simulate a response.
65+
// When time sync is disabled, do NOT simulate a time sync response.
4166
await new Promise(resolve => setTimeout(resolve, 300));
4267
console.log(`${methodName} -> timeDiff: ${client.timeDiff.toFixed(6)} sec (should remain ${previousTimeDiff.toFixed(6)} sec)`);
4368
// Re-enable time sync for subsequent tests.
4469
client.setEnableTimeSync(true);
4570
}
4671

4772
async function runTest() {
48-
// Create a new client instance with only endpoint and autoReconnect.
73+
// Create a new client instance.
4974
client = new Client('127.0.0.1:17000', true);
5075

51-
// Override _sendTimeRequest to simulate an immediate server time response with variable delay.
76+
// Override _sendTimeRequest to simulate a server time response with variable delay.
5277
client._sendTimeRequest = function (requestId) {
5378
console.log(`_sendTimeRequest called with requestId: ${requestId}`);
54-
// Simulate variable network delay (e.g., 50 to 300ms)
5579
const delay = Math.floor(Math.random() * 250) + 50;
5680
setTimeout(() => {
57-
// Simulate a server timestamp in nanoseconds.
5881
const simulatedTimestamp = Date.now() * 1e6;
5982
console.log(`Simulated timestamp for request ${requestId} after ${delay}ms: ${simulatedTimestamp}`);
60-
if (client.storedPromises[requestId]) {
61-
client.storedPromises[requestId].resolve(simulatedTimestamp);
62-
delete client.storedPromises[requestId];
83+
if (this.storedPromises[requestId]) {
84+
this.storedPromises[requestId].resolve(simulatedTimestamp);
85+
delete this.storedPromises[requestId];
6386
}
6487
}, delay);
6588
};
6689

67-
// Override _updateTimeDiff to perform one measurement and log its details.
90+
// Override _updateTimeDiff to log the measurement.
6891
client._updateTimeDiff = function () {
6992
if (!this.enableTimeSync) return;
7093
const requestId = this._getRequestId();
7194
const timeSent = Date.now() / 1000;
72-
// Call _requestTime (which now calls our overridden _sendTimeRequest).
7395
this._requestTime(requestId)
7496
.then(timestamp => {
75-
// Simulate a time response arriving.
7697
this.timeReceived = Date.now() / 1000;
7798
const roundTripTime = this.timeReceived - timeSent;
7899
const serverTime = (timestamp / 1e9) + roundTripTime / 2;
@@ -88,46 +109,73 @@ async function runTest() {
88109
.catch(err => console.error(err));
89110
};
90111

91-
// Use the production _requestTime (which already checks enableTimeSync).
92-
// No override needed here.
93-
94-
// Now run through several public API methods.
112+
// Run tests for each public API method.
95113
await runThrough(
96114
"requestApiVersion",
97115
() => client.requestApiVersion(),
98-
() => {
99-
// Simulate a valid API version response.
100-
const response = fakeData.createApiVersionResponse();
101-
client._parseMessage(response);
116+
(timeSyncId, apiId) => {
117+
// Simulate time sync response.
118+
const timeResponse = {
119+
messageType: fakeData.Container.Type.eTimeResponse,
120+
timeResponse: { requestId: timeSyncId, timestamp: Date.now() * 1e6 }
121+
};
122+
client._parseMessage(timeResponse);
123+
// Simulate API version response.
124+
const apiResponse = fakeData.createApiVersionResponse(apiId);
125+
client._parseMessage(apiResponse);
102126
}
103127
);
104128

105129
await runThrough(
106130
"requestLogLimits",
107131
() => client.requestLogLimits(),
108-
() => {
109-
const response = fakeData.createLogLimitsResponse();
110-
client._parseMessage(response);
132+
(timeSyncId, apiId) => {
133+
const timeResponse = {
134+
messageType: fakeData.Container.Type.eTimeResponse,
135+
timeResponse: { requestId: timeSyncId, timestamp: Date.now() * 1e6 }
136+
};
137+
client._parseMessage(timeResponse);
138+
const apiResponse = fakeData.createLogLimitsResponse(apiId);
139+
client._parseMessage(apiResponse);
111140
}
112141
);
113142

114143
await runThrough(
115144
"requestLoggedNodes",
116145
() => client.requestLoggedNodes(),
117-
() => {
118-
const response = fakeData.createLoggedNodesResponse(1);
119-
client._parseMessage(response);
146+
(timeSyncId, apiId) => {
147+
const timeResponse = {
148+
messageType: fakeData.Container.Type.eTimeResponse,
149+
timeResponse: { requestId: timeSyncId, timestamp: Date.now() * 1e6 }
150+
};
151+
client._parseMessage(timeResponse);
152+
const apiResponse = fakeData.createLoggedNodesResponse(apiId);
153+
client._parseMessage(apiResponse);
120154
}
121155
);
122156

157+
// Ensure that the node mapping includes "CPULoad" before calling requestDataPoints.
158+
if (!("CPULoad" in client.nameToId)) {
159+
console.log("Mapping missing CPULoad. Simulating logged nodes response to update mapping.");
160+
client._parseMessage(fakeData.createLoggedNodesResponse(999));
161+
}
162+
123163
await runThrough(
124164
"requestDataPoints",
125165
() => client.requestDataPoints(["Output", "CPULoad"], 1531313250.0, 1531461231.0, 500),
126-
() => {
127-
const response = fakeData.createDataPointResponse();
128-
client._parseMessage(response);
166+
(timeSyncId, apiId) => {
167+
const timeResponse = {
168+
messageType: fakeData.Container.Type.eTimeResponse,
169+
timeResponse: { requestId: timeSyncId, timestamp: Date.now() * 1e6 }
170+
};
171+
client._parseMessage(timeResponse);
172+
const apiResponse = fakeData.createDataPointResponse(apiId);
173+
client._parseMessage(apiResponse);
129174
}
130175
);
176+
177+
// Disconnect the client to close the open WebSocket and allow the process to exit.
178+
client.disconnect();
131179
}
132180

133181
let client;

0 commit comments

Comments
 (0)