mirror of
https://github.com/xCyanGrizzly/DragonsStash.git
synced 2026-05-10 22:01:16 +00:00
Fix review issues: race condition in invokeWithTimeout and mutex queue entry
- Add settled flag to invokeWithTimeout to prevent double-settling - Create mutex queue entry with wrapped resolve before pushing to queue Co-authored-by: xCyanGrizzly <53275238+xCyanGrizzly@users.noreply.github.com>
This commit is contained in:
@@ -88,18 +88,29 @@ export async function invokeWithTimeout<T>(
|
||||
timeoutMs = INVOKE_TIMEOUT_MS
|
||||
): Promise<T> {
|
||||
return new Promise<T>((resolve, reject) => {
|
||||
let settled = false;
|
||||
|
||||
const timer = setTimeout(() => {
|
||||
reject(new Error(`TDLib invoke timed out after ${timeoutMs}ms for ${request._}`));
|
||||
if (!settled) {
|
||||
settled = true;
|
||||
reject(new Error(`TDLib invoke timed out after ${timeoutMs}ms for ${request._}`));
|
||||
}
|
||||
}, timeoutMs);
|
||||
|
||||
(client.invoke(request) as Promise<T>)
|
||||
.then((result) => {
|
||||
clearTimeout(timer);
|
||||
resolve(result);
|
||||
if (!settled) {
|
||||
settled = true;
|
||||
clearTimeout(timer);
|
||||
resolve(result);
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
clearTimeout(timer);
|
||||
reject(err);
|
||||
if (!settled) {
|
||||
settled = true;
|
||||
clearTimeout(timer);
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -27,10 +27,6 @@ export async function withTdlibMutex<T>(
|
||||
if (locked) {
|
||||
log.info({ waiting: label, holder }, "Waiting for TDLib mutex");
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
const entry = { resolve, reject, label };
|
||||
queue.push(entry);
|
||||
|
||||
// Timeout: reject if we've been waiting too long
|
||||
const timer = setTimeout(() => {
|
||||
const idx = queue.indexOf(entry);
|
||||
if (idx !== -1) {
|
||||
@@ -42,12 +38,15 @@ export async function withTdlibMutex<T>(
|
||||
}
|
||||
}, MUTEX_WAIT_TIMEOUT_MS);
|
||||
|
||||
// Wrap resolve to clear the timer
|
||||
const origResolve = entry.resolve;
|
||||
entry.resolve = () => {
|
||||
clearTimeout(timer);
|
||||
origResolve();
|
||||
const entry = {
|
||||
resolve: () => {
|
||||
clearTimeout(timer);
|
||||
resolve();
|
||||
},
|
||||
reject,
|
||||
label,
|
||||
};
|
||||
queue.push(entry);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user