diff --git a/lib/cache.ts b/lib/cache.ts index fb8223a..98d9987 100644 --- a/lib/cache.ts +++ b/lib/cache.ts @@ -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; diff --git a/lib/cwmp.ts b/lib/cwmp.ts index 43d7d4e..e9423b6 100644 --- a/lib/cwmp.ts +++ b/lib/cwmp.ts @@ -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, diff --git a/lib/local-cache.ts b/lib/local-cache.ts index 04e6277..eb3e62f 100644 --- a/lib/local-cache.ts +++ b/lib/local-cache.ts @@ -380,13 +380,15 @@ async function fetchConfig(): Promise<[Config, UiConfig]> { async function refresh(): Promise { 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 { 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 { 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)); }