Transpiled version (10117L) is out of date.
// the lockFile must be a file separate from any data files. // It is created & deleted by this class, and will always have // size 0. sclass FileBasedLock implements AutoCloseable { File lockFile; double timeout = 60.0; // in seconds. refresh happens twice as often bool verbose; bool haveLock; java.util.Timer touchTimer; // what to put in the lock file when we create it settable S contentsForLockFile; *() {} *(File *lockFile) {} *(File *lockFile, double *timeout) {} // returns true iff lock was acquired (or kept) synchronized bool tryToLock() { if (haveLock) true; if (fileExists(lockFile)) { double age = fileAgeInSeconds(lockFile); double remaining = timeout-age; print("Lock file age: " + lockFile + ": " + iround(age) + " s" + (remaining <= 0 ? " - old, deleting" : " - please start again in " + nSeconds(iceil(remaining)))); if (remaining <= 0) { print("Deleting old lock file (program crashed?): " + lockFile + " (age: " + iround(age) + " seconds)"); deleteFile(lockFile); } } try { mkdirsForFile(lockFile); // This does the actual atomic file creation java.nio.file.Files.createFile(toPath(lockFile)); print("Created lock file: " + lockFile); // Optionally set the lock file's contents if (nempty(contentsForLockFile)) writeContents(); acquired(); true; } catch e { printExceptionShort("Can't lock", e); false; } } void writeContents { saveTextFileWithoutTemp(lockFile, unnull(contentsForLockFile)); } private void acquired { set haveLock; startTouchTimer(); } void forceLock ctex { print("Force-locking " + lockFile); writeContents(); acquired(); } S lockError() { ret "Couldn't aquire lock file: " + lockFile; } void lockOrFail { if (!tryToLock()) fail(lockError()); } synchronized void startTouchTimer { if (touchTimer != null) ret; double interval = timeout/2; touchTimer = doEvery(interval, r doTouch); if (verbose) print("Touch timer started for " + lockFile + " (" + interval + "s)"); } synchronized void doTouch() pcall { if (haveLock) { if (verbose) print("Touching lock file: " + lockFile); //touchExistingFile(lockFile); touchFile(lockFile); } } public synchronized void close() pcall { dispose touchTimer; if (haveLock) { haveLock = false; if (verbose) print("Deleting lock file: " + lockFile); deleteFile(lockFile); } } synchronized void _simulateCrash { dispose touchTimer; } void deleteOnExit { if (haveLock) lockFile.deleteOnExit(); } S actualContents() { ret loadTextFile(lockFile); } bool hasExpectedContents() { ret eq(unnull(contentsForLockFile), actualContents()); } }
download show line numbers debug dex old transpilations
Travelled to 6 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1029788 |
Snippet name: | FileBasedLock (crash-safe, should work even over NFS) |
Eternal ID of this version: | #1029788/44 |
Text MD5: | 38f91f36d9d25d5119cdc81c262e7b1f |
Author: | stefan |
Category: | javax / io |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2022-11-30 16:56:19 |
Source code size: | 3082 bytes / 119 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 373 / 843 |
Version history: | 43 change(s) |
Referenced in: | [show references] |