Reclaim stale script lock after crash (v1.3.1)
The single-tab lock was only released in beforeunload, so a browser crash or power-cut left the localStorage key behind and the script exited on every subsequent load until site data was cleared. Treat a lock not refreshed within 90s as dead and take it over, and add a 30s heartbeat so a live instance keeps its lock fresh. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
31
cams.user.js
31
cams.user.js
@@ -1,7 +1,7 @@
|
||||
// ==UserScript==
|
||||
// @name cams
|
||||
// @namespace http://tampermonkey.net/
|
||||
// @version 1.3.0
|
||||
// @version 1.3.1
|
||||
// @description Set maxDockedCamsForUser, keep-alive, and multi-poke
|
||||
// @author You
|
||||
// @match https://chat.fabswingers.com/*
|
||||
@@ -223,18 +223,37 @@
|
||||
localStorage.setItem(KEEPALIVE_SETTINGS_KEY, JSON.stringify(keepAliveSettings));
|
||||
}
|
||||
|
||||
// Try to acquire lock
|
||||
const lockValue = Date.now().toString();
|
||||
// Try to acquire lock.
|
||||
// The lock value is a timestamp that a live instance refreshes on a heartbeat.
|
||||
// If a crash / power-cut kills the tab, beforeunload never fires and the key is
|
||||
// left behind; a new load treats a lock older than LOCK_STALE_MS as dead and
|
||||
// takes over, instead of exiting forever (which required clearing site data).
|
||||
const LOCK_STALE_MS = 90 * 1000; // reclaim a lock not refreshed within 90s
|
||||
const LOCK_HEARTBEAT_MS = 30 * 1000; // refresh our lock every 30s while alive
|
||||
let ourLockValue = Date.now().toString();
|
||||
|
||||
if (localStorage.getItem(LOCK_KEY)) {
|
||||
const existingLock = localStorage.getItem(LOCK_KEY);
|
||||
if (existingLock) {
|
||||
const lockAge = Date.now() - parseInt(existingLock, 10);
|
||||
if (isNaN(lockAge) || lockAge < LOCK_STALE_MS) {
|
||||
console.log('MaxDockedCams: Another instance already running, exiting');
|
||||
return;
|
||||
}
|
||||
console.log(`MaxDockedCams: Reclaiming stale lock (${Math.round(lockAge / 1000)}s old)`);
|
||||
}
|
||||
|
||||
localStorage.setItem(LOCK_KEY, lockValue);
|
||||
localStorage.setItem(LOCK_KEY, ourLockValue);
|
||||
|
||||
// Keep our lock fresh so a live instance is never mistaken for a crashed one.
|
||||
setInterval(function() {
|
||||
if (localStorage.getItem(LOCK_KEY) === ourLockValue) {
|
||||
ourLockValue = Date.now().toString();
|
||||
localStorage.setItem(LOCK_KEY, ourLockValue);
|
||||
}
|
||||
}, LOCK_HEARTBEAT_MS);
|
||||
|
||||
window.addEventListener('beforeunload', function() {
|
||||
if (localStorage.getItem(LOCK_KEY) === lockValue) {
|
||||
if (localStorage.getItem(LOCK_KEY) === ourLockValue) {
|
||||
localStorage.removeItem(LOCK_KEY);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user