Skip to content

Commit 5f78055

Browse files
committed
fix: gracefully close the web socket before exiting
1 parent 8059bac commit 5f78055

File tree

2 files changed

+77
-64
lines changed

2 files changed

+77
-64
lines changed

src/APIClient.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,4 +198,10 @@ export class APIClient {
198198
console.error('Unknown response', message);
199199
}
200200
}
201+
202+
close() {
203+
if (this.socket.readyState === WebSocket.OPEN) {
204+
this.socket.close();
205+
}
206+
}
201207
}

src/main.ts

Lines changed: 71 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ async function main() {
134134
console.log(chalk`\n\nExpected text found: {green "${expectText}"}`);
135135
console.log('TEST PASSED.');
136136
}
137+
client.close();
137138
process.exit(0);
138139
});
139140
}
@@ -147,88 +148,94 @@ async function main() {
147148

148149
console.error(chalk`\n\n{red Error:} Unexpected text found: {yellow "${text}"}`);
149150
console.error('TEST FAILED.');
151+
client.close();
150152
process.exit(1);
151153
});
152154
}
153155

154156
const client = new APIClient(token);
155-
client.onConnected = (hello) => {
156-
if (!quiet) {
157-
console.log(`Connected to Wokwi Simulation API ${hello.appVersion}`);
157+
try {
158+
client.onConnected = (hello) => {
159+
if (!quiet) {
160+
console.log(`Connected to Wokwi Simulation API ${hello.appVersion}`);
161+
}
162+
};
163+
await client.connected;
164+
await client.fileUpload('diagram.json', diagram);
165+
const extension = firmwarePath.split('.').pop();
166+
const firmwareName = `firmware.${extension}`;
167+
await client.fileUpload(firmwareName, readFileSync(firmwarePath));
168+
await client.fileUpload('firmware.elf', readFileSync(elfPath));
169+
170+
for (const chip of chips) {
171+
await client.fileUpload(`${chip.name}.chip.json`, readFileSync(chip.jsonPath, 'utf-8'));
172+
await client.fileUpload(`${chip.name}.chip.wasm`, readFileSync(chip.wasmPath));
158173
}
159-
};
160-
await client.connected;
161-
await client.fileUpload('diagram.json', diagram);
162-
const extension = firmwarePath.split('.').pop();
163-
const firmwareName = `firmware.${extension}`;
164-
await client.fileUpload(firmwareName, readFileSync(firmwarePath));
165-
await client.fileUpload('firmware.elf', readFileSync(elfPath));
166-
167-
for (const chip of chips) {
168-
await client.fileUpload(`${chip.name}.chip.json`, readFileSync(chip.jsonPath, 'utf-8'));
169-
await client.fileUpload(`${chip.name}.chip.wasm`, readFileSync(chip.wasmPath));
170-
}
171-
172-
if (!quiet) {
173-
console.log('Starting simulation...');
174-
}
175174

176-
const scenarioPromise = scenario?.start(client);
175+
if (!quiet) {
176+
console.log('Starting simulation...');
177+
}
177178

178-
if (timeoutNanos) {
179-
eventManager.at(timeoutNanos, () => {
180-
// We are using setImmediate to make sure other events (e.g. screen shot) are processed first
181-
setImmediate(() => {
182-
void eventManager.eventHandlersInProgress.then(() => {
183-
console.error(`Timeout: simulation did not finish in ${timeout}ms`);
184-
process.exit(timeoutExitCode);
179+
const scenarioPromise = scenario?.start(client);
180+
181+
if (timeoutNanos) {
182+
eventManager.at(timeoutNanos, () => {
183+
// We are using setImmediate to make sure other events (e.g. screen shot) are processed first
184+
setImmediate(() => {
185+
void eventManager.eventHandlersInProgress.then(() => {
186+
console.error(`Timeout: simulation did not finish in ${timeout}ms`);
187+
client.close();
188+
process.exit(timeoutExitCode);
189+
});
185190
});
186191
});
187-
});
188-
}
192+
}
189193

190-
if (screenshotPart != null && screenshotTime != null) {
191-
eventManager.at(screenshotTime * millis, async (t) => {
192-
const result = await client.framebufferRead(screenshotPart);
193-
writeFileSync(screenshotFile, result.png, 'base64');
194-
});
195-
}
194+
if (screenshotPart != null && screenshotTime != null) {
195+
eventManager.at(screenshotTime * millis, async (t) => {
196+
const result = await client.framebufferRead(screenshotPart);
197+
writeFileSync(screenshotFile, result.png, 'base64');
198+
});
199+
}
196200

197-
await client.serialMonitorListen();
198-
const { timeToNextEvent } = eventManager;
201+
await client.serialMonitorListen();
202+
const { timeToNextEvent } = eventManager;
199203

200-
client.onEvent = (event) => {
201-
if (event.event === 'sim:pause') {
202-
eventManager.processEvents(event.nanos);
203-
if (eventManager.timeToNextEvent >= 0) {
204-
void client.simResume(eventManager.timeToNextEvent);
204+
client.onEvent = (event) => {
205+
if (event.event === 'sim:pause') {
206+
eventManager.processEvents(event.nanos);
207+
if (eventManager.timeToNextEvent >= 0) {
208+
void client.simResume(eventManager.timeToNextEvent);
209+
}
205210
}
206-
}
207-
if (event.event === 'serial-monitor:data') {
208-
const { bytes } = (event as APIEvent<SerialMonitorDataPayload>).payload;
209-
for (const byte of bytes) {
210-
process.stdout.write(String.fromCharCode(byte));
211+
if (event.event === 'serial-monitor:data') {
212+
const { bytes } = (event as APIEvent<SerialMonitorDataPayload>).payload;
213+
for (const byte of bytes) {
214+
process.stdout.write(String.fromCharCode(byte));
215+
}
216+
expectEngine.feed(bytes);
211217
}
212-
expectEngine.feed(bytes);
213-
}
214-
if (event.event === 'chips:log') {
215-
const { message, chip } = (event as APIEvent<ChipsLogPayload>).payload;
216-
console.log(chalk`[{magenta ${chip}}] ${message}`);
217-
}
218-
};
218+
if (event.event === 'chips:log') {
219+
const { message, chip } = (event as APIEvent<ChipsLogPayload>).payload;
220+
console.log(chalk`[{magenta ${chip}}] ${message}`);
221+
}
222+
};
223+
224+
await client.simStart({
225+
elf: 'test.elf',
226+
firmware: firmwareName,
227+
chips: chips.map((chip) => chip.name),
228+
pause: timeToNextEvent >= 0,
229+
});
219230

220-
await client.simStart({
221-
elf: 'test.elf',
222-
firmware: firmwareName,
223-
chips: chips.map((chip) => chip.name),
224-
pause: timeToNextEvent >= 0,
225-
});
231+
if (timeToNextEvent > 0) {
232+
await client.simResume(timeToNextEvent);
233+
}
226234

227-
if (timeToNextEvent > 0) {
228-
await client.simResume(timeToNextEvent);
235+
await scenarioPromise;
236+
} finally {
237+
client.close();
229238
}
230-
231-
await scenarioPromise;
232239
}
233240

234241
main().catch((err) => {

0 commit comments

Comments
 (0)