I am using GenieACS version 1.2.8 with modular deployment (2 nodes of GenieACS and 3 nodes of MongoDB replica set). It was fine for a long time until the day I met the genieacs-cwmp service failed issue with the below error logs
acs01 genieacs-cwmp: 2023-10-22T02:35:23.982Z [ERROR] Uncaught exception; pid=61527 exceptionName="Error" exceptionMessage="Database clock skew too great" exceptionStack="Error: Database clock skew too great\n at async (/usr/lib/node_modules/lib/cache.ts:87:13)\n at runMicrotasks (<anonymous>)\n at processTicksAndRejections (internal/process/task_queues.js:95:5)\n at async (/usr/lib/node_modules/lib/cwmp.ts:214:41)"
acs01 genieacs-cwmp: 2023-10-22T02:35:32.479Z [ERROR] Uncaught exception; pid=61902 exceptionName="MongoNotConnectedError" exceptionMessage="MongoClient must be connected to perform this operation" exceptionStack="/usr/lib/node_modules/genieacs/node_modules/mongodb/src/utils.ts:476\n throw new MongoNotConnectedError('MongoClient must be connected to perform this operation');\n ^\n\nMongoNotConnectedError: MongoClient must be connected to perform this operation\n at Object.getTopology (/usr/lib/node_modules/genieacs/node_modules/mongodb/src/utils.ts:476:9)\n at Collection.deleteOne (/usr/lib/node_modules/genieacs/node_modules/mongodb/src/collection.ts:570:7)\n at async (/usr/lib/node_modules/lib/cache.ts:113:37)\n at async (/usr/lib/node_modules/lib/cwmp.ts:828:9)\n at processTicksAndRejections (internal/process/task_queues.js:95:5)\n at async (/usr/lib/node_modules/lib/cwmp.ts:207:29)"
I just took a quick look at the source code that contains the above printed logs (genieacs/lib/cache.ts)
export async function acquireLock(
lockName: string,
ttl: number,
timeout = 0,
token = Math.random().toString(36).slice(2)
): Promise<string> {
try {
const now = Date.now();
const r = await cacheCollection.findOneAndUpdate(
{ _id: lockName, value: token },
{
$set: {
expire: new Date(now + ttl + CLOCK_SKEW_TOLERANCE),
},
$currentDate: { timestamp: true },
},
{ upsert: true, returnDocument: "after" }
);
if (Math.abs(r.value.timestamp.getTime() - now) > CLOCK_SKEW_TOLERANCE)
throw new Error("Database clock skew too great");
} catch (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;
}
So, what is the meaning of CLOCK_SKEW_TOLERANCE in this code block?
And, could anyone give me an example of when could “Database clock skew too great” happen?
Thank you so much~