fix(login): release timed-out request callbacks and correct takeover response

This commit is contained in:
max bittker committed 2026-09-28 18:44:06 -04:00
1 parent 9dc413c490
commit c7a94502a9
3 files changed
+58 -23

No files matched your search

+24 -22
View File
@@ -86,33 +86,35 @@ export default class WsSyncReq {
'onIncomingCallback': callbackOnIncoming,
'expectedObject': expectedObj,
};
const data_new = this.cloneObjectDestructuve (dataToSend);
data_new[this.keyOfRequestId] = uniqueId;
try {
const data_new = this.cloneObjectDestructuve (dataToSend);
data_new[this.keyOfRequestId] = uniqueId;
if (this.send(data_new)) {
let start = Date.now();
while (true) {
if (!this.checkIfWsLive()) {
delete this.waitedSyncCallbacks[uniqueId];
return { error : 'ws-sync - connection lost: ' + uniqueId, result:null};
} else if ((Date.now() - start) > timeoutMs) {
return { error : 'ws-sync - exceeded timeout: ' + uniqueId, result:null};
} else {
await this.sleep(this.loopPauseWaitIntervalMS);
if (uniqueId in this.waitedSyncCallbacks) {
const value = this.waitedSyncCallbacks[uniqueId];
if (value['result'] != null) {
delete this.waitedSyncCallbacks[uniqueId];
return { error: null, result: value['result'] };
}
if (this.send(data_new)) {
let start = Date.now();
while (true) {
if (!this.checkIfWsLive()) {
return { error : 'ws-sync - connection lost: ' + uniqueId, result:null};
} else if ((Date.now() - start) > timeoutMs) {
return { error : 'ws-sync - exceeded timeout: ' + uniqueId, result:null};
} else {
var msg = 'ws-sync - unexpected exception, this should not be happen... the unique id does not exist: ' + uniqueId;
return { error : msg, result:null };
await this.sleep(this.loopPauseWaitIntervalMS);
if (uniqueId in this.waitedSyncCallbacks) {
const value = this.waitedSyncCallbacks[uniqueId];
if (value['result'] != null) {
return { error: null, result: value['result'] };
}
} else {
var msg = 'ws-sync - unexpected exception, this should not be happen... the unique id does not exist: ' + uniqueId;
return { error : msg, result:null };
}
}
}
} else {
return { error : 'ws-sync - failed to send request. Socket may be disconnected', result:null };
}
} else {
return { error : 'ws-sync - failed to send request. Socket may be disconnected', result:null };
} finally {
delete this.waitedSyncCallbacks[uniqueId];
}
}
@@ -546,7 +546,7 @@ export default class LoginServer {
s.send(
JSON.stringify({
replyTo,
response: 5
response: 3
})
);
return;
+33
View File
@@ -0,0 +1,33 @@
import { expect, test } from 'bun:test';
import { EventEmitter } from 'node:events';
import WsSyncReq from '../src/3rdparty/ws-sync/ws-sync.js';
class FakeSocket extends EventEmitter {
readyState = 1;
sent: string[] = [];
send(data: string) {
this.sent.push(data);
}
}
test('login reply callbacks are released after timeout, response, and failed send', async () => {
const socket = new FakeSocket();
const client = new WsSyncReq(socket);
client.loopPauseWaitIntervalMS = 1;
const pending = client.fetchSync({ type: 'player_login' }, 10);
expect(Object.keys(client.waitedSyncCallbacks)).toHaveLength(1);
expect((await pending).error).toContain('exceeded timeout');
expect(Object.keys(client.waitedSyncCallbacks)).toHaveLength(0);
const accepted = client.fetchSync({ type: 'player_login' }, 1000);
const { replyTo } = JSON.parse(socket.sent.at(-1)!);
socket.emit('message', Buffer.from(JSON.stringify({ replyTo, response: 0 })));
expect((await accepted).result.response).toBe(0);
expect(Object.keys(client.waitedSyncCallbacks)).toHaveLength(0);
socket.readyState = 3;
expect((await client.fetchSync({ type: 'player_login' })).error).toContain('failed to send');
expect(Object.keys(client.waitedSyncCallbacks)).toHaveLength(0);
});