mirror of
https://github.com/xCyanGrizzly/DragonsStash.git
synced 2026-05-11 06:11:15 +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
|
timeoutMs = INVOKE_TIMEOUT_MS
|
||||||
): Promise<T> {
|
): Promise<T> {
|
||||||
return new Promise<T>((resolve, reject) => {
|
return new Promise<T>((resolve, reject) => {
|
||||||
|
let settled = false;
|
||||||
|
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
|
if (!settled) {
|
||||||
|
settled = true;
|
||||||
reject(new Error(`TDLib invoke timed out after ${timeoutMs}ms for ${request._}`));
|
reject(new Error(`TDLib invoke timed out after ${timeoutMs}ms for ${request._}`));
|
||||||
|
}
|
||||||
}, timeoutMs);
|
}, timeoutMs);
|
||||||
|
|
||||||
(client.invoke(request) as Promise<T>)
|
(client.invoke(request) as Promise<T>)
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
|
if (!settled) {
|
||||||
|
settled = true;
|
||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
resolve(result);
|
resolve(result);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
|
if (!settled) {
|
||||||
|
settled = true;
|
||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
reject(err);
|
reject(err);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,10 +27,6 @@ export async function withTdlibMutex<T>(
|
|||||||
if (locked) {
|
if (locked) {
|
||||||
log.info({ waiting: label, holder }, "Waiting for TDLib mutex");
|
log.info({ waiting: label, holder }, "Waiting for TDLib mutex");
|
||||||
await new Promise<void>((resolve, reject) => {
|
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 timer = setTimeout(() => {
|
||||||
const idx = queue.indexOf(entry);
|
const idx = queue.indexOf(entry);
|
||||||
if (idx !== -1) {
|
if (idx !== -1) {
|
||||||
@@ -42,12 +38,15 @@ export async function withTdlibMutex<T>(
|
|||||||
}
|
}
|
||||||
}, MUTEX_WAIT_TIMEOUT_MS);
|
}, MUTEX_WAIT_TIMEOUT_MS);
|
||||||
|
|
||||||
// Wrap resolve to clear the timer
|
const entry = {
|
||||||
const origResolve = entry.resolve;
|
resolve: () => {
|
||||||
entry.resolve = () => {
|
|
||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
origResolve();
|
resolve();
|
||||||
|
},
|
||||||
|
reject,
|
||||||
|
label,
|
||||||
};
|
};
|
||||||
|
queue.push(entry);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user