Better locking in local cache
Fixes occassional lock expired errors after updating presets, etc.
This commit is contained in:
1 parent
eb5caa6b5a
commit
5806fe2df6
3 files changed
+19
-22
No files matched your search
+4
-14
@@ -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) => {
|
||||
if (err.code !== 11000) throw err;
|
||||
if (!(timeout > 0)) return null;
|
||||
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;
|
||||
await new Promise((resolve) => setTimeout(resolve, w));
|
||||
return acquireLock(lockName, ttl, timeout - w, token);
|
||||
}
|
||||
|
||||
return token;
|
||||
|
||||
+5
-4
@@ -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(
|
||||
const lockToken = await cache.acquireLock(
|
||||
`cwmp_session_${sessionContext.deviceId}`,
|
||||
sessionContext.timeout * 1000 + 15000,
|
||||
0,
|
||||
sessionContext.sessionId
|
||||
);
|
||||
} catch (err) {
|
||||
|
||||
if (!lockToken) {
|
||||
logger.accessError({
|
||||
message: "CPE already in session",
|
||||
sessionContext: sessionContext,
|
||||
|
||||
+10
-4
@@ -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);
|
||||
|
||||
if (lockToken) {
|
||||
if (currentSnapshot !== dbHash)
|
||||
await cache.set("presets_hash", currentSnapshot, 300);
|
||||
await cache.releaseLock("presets_hash_lock", lockToken);
|
||||
}
|
||||
|
||||
nextRefresh = now + (REFRESH - (now % REFRESH));
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user