Better locking in local cache

Fixes occassional lock expired errors after updating presets, etc.
This commit is contained in:
Zaid Abdulla committed 2022-08-12 01:11:04 -07:00
1 parent eb5caa6b5a
commit 5806fe2df6
3 files changed
+28 -31

No files matched your search

+5 -15
View File
@@ -86,21 +86,11 @@ export async function acquireLock(
if (Math.abs(v["timestamp"].getTime() - now) > CLOCK_SKEW_TOLERANCE)
throw new Error("Database clock skew too great");
} catch (err) {
if (err.code === 11000) {
if (timeout > 0) {
return new Promise((resolve, reject) => {
const w = 50 + Math.random() * 50;
setTimeout(() => {
acquireLock(lockName, ttl, timeout - w, token).then(
resolve,
reject
);
}, w);
});
}
throw new Error("Failed to acquire lock");
}
throw err;
if (err.code !== 11000) throw err;
if (!(timeout > 0)) return null;
const w = 50 + Math.random() * 50;
await new Promise((resolve) => setTimeout(resolve, w));
return acquireLock(lockName, ttl, timeout - w, token);
}
return token;
+11 -10
View File
@@ -213,12 +213,13 @@ async function writeResponse(
currentSessions.set(connection, sessionContext);
if (now >= sessionContext.extendLock) {
sessionContext.extendLock = now + 10000;
await cache.acquireLock(
const lockToken = await cache.acquireLock(
`cwmp_session_${sessionContext.deviceId}`,
sessionContext.timeout * 1000 + 15000,
0,
sessionContext.sessionId
);
if (!lockToken) throw new Error("Failed to extend lock");
}
}
}
@@ -1149,15 +1150,15 @@ async function processRequest(
}
}
try {
sessionContext.extendLock = sessionContext.timestamp + 10000;
await cache.acquireLock(
`cwmp_session_${sessionContext.deviceId}`,
sessionContext.timeout * 1000 + 15000,
0,
sessionContext.sessionId
);
} catch (err) {
sessionContext.extendLock = sessionContext.timestamp + 10000;
const lockToken = await cache.acquireLock(
`cwmp_session_${sessionContext.deviceId}`,
sessionContext.timeout * 1000 + 15000,
0,
sessionContext.sessionId
);
if (!lockToken) {
logger.accessError({
message: "CPE already in session",
sessionContext: sessionContext,
+12 -6
View File
@@ -380,13 +380,15 @@ async function fetchConfig(): Promise<[Config, UiConfig]> {
async function refresh(): Promise<void> {
if (!nextRefresh) {
await new Promise((resolve) => setTimeout(resolve, 20));
await refresh();
return;
return refresh();
}
nextRefresh = 0;
const now = Date.now();
if (now < nextRefresh) return;
nextRefresh = 0;
const dbHash = await cache.get("presets_hash");
if (currentSnapshot && dbHash === currentSnapshot) {
@@ -394,7 +396,7 @@ async function refresh(): Promise<void> {
return;
}
const lockToken = await cache.acquireLock("presets_hash_lock", 5000, 5000);
const lockToken = await cache.acquireLock("presets_hash_lock", 5000);
const res = await Promise.all([
fetchPresets(),
@@ -427,8 +429,12 @@ async function refresh(): Promise<void> {
currentSnapshot = computeHash(snapshot);
snapshots.set(currentSnapshot, snapshot);
await cache.set("presets_hash", currentSnapshot, 300);
await cache.releaseLock("presets_hash_lock", lockToken);
if (lockToken) {
if (currentSnapshot !== dbHash)
await cache.set("presets_hash", currentSnapshot, 300);
await cache.releaseLock("presets_hash_lock", lockToken);
}
nextRefresh = now + (REFRESH - (now % REFRESH));
}