### Use Custom Filesystem with proper-lockfile Source: https://context7.com/moxystudio/node-proper-lockfile/llms.txt Demonstrates how to use a custom filesystem implementation, such as 'memfs' or a mock object, with proper-lockfile. This is useful for testing scenarios or environments with specific filesystem requirements. The 'fs' option in lockfile.lock accepts a custom filesystem object. ```javascript const lockfile = require('proper-lockfile'); const fs = require('fs'); const memfs = require('memfs'); // Using memory filesystem for testing async function withCustomFs() { const vol = memfs.Volume.fromJSON({ '/tmp/file.txt': 'content' }); const release = await lockfile.lock('/tmp/file.txt', { fs: vol, // Use custom fs implementation realpath: false }); // Operations using the custom fs vol.writeFileSync('/tmp/file.txt', 'updated'); await release(); } // Mock filesystem for testing async function testWithMock() { const mockFs = { mkdir: jest.fn((path, cb) => cb(null)), rmdir: jest.fn((path, cb) => cb(null)), stat: jest.fn((path, cb) => cb(null, { mtime: new Date() })), utimes: jest.fn((path, atime, mtime, cb) => cb(null)), realpath: jest.fn((path, cb) => cb(null, path)) }; await lockfile.lock('/tmp/file.txt', { fs: mockFs, stale: 10000 }); expect(mockFs.mkdir).toHaveBeenCalled(); } ``` -------------------------------- ### Acquire and Release File Lock Asynchronously (JavaScript) Source: https://github.com/moxystudio/node-proper-lockfile/blob/master/README.md Demonstrates how to acquire a lock on a file using `proper-lockfile` and then release it. The `lock` function returns a promise that resolves with a `release` function. This `release` function must be called to free the lock. Error handling for both acquisition and release is included. Dependencies: 'proper-lockfile'. ```javascript const lockfile = require('proper-lockfile'); lockfile.lock('some/file') .then((release) => { // Do something while the file is locked // Call the provided release function when you're done, // which will also return a promise return release(); }) .catch((e) => { // either lock could not be acquired // or releasing it failed console.error(e) }); // Alternatively, you may use lockfile('some/file') directly. ``` -------------------------------- ### Release File Lock Asynchronously (JavaScript) Source: https://github.com/moxystudio/node-proper-lockfile/blob/master/README.md Shows how to release a previously acquired file lock using `proper-lockfile.unlock`. While using the `release` function returned by `lock` is preferred, `unlock` can be used when a reference to `release` is not readily available. Dependencies: 'proper-lockfile'. ```javascript const lockfile = require('proper-lockfile'); lockfile.lock('some/file') .then(() => { // Do something while the file is locked // Later.. return lockfile.unlock('some/file'); }); ``` -------------------------------- ### Acquire File Lock Synchronously (JavaScript) Source: https://github.com/moxystudio/node-proper-lockfile/blob/master/README.md Presents the synchronous version of acquiring a file lock using `proper-lockfile.lockSync`. This function returns a `release` function upon success or throws an error if the lock cannot be acquired. Dependencies: 'proper-lockfile'. ```javascript const lockfile = require('proper-lockfile'); try { const release = lockfile.lockSync('some/file'); // Do something while the file is locked release(); // Release the lock } catch (e) { console.error('Failed to acquire or release lock:', e); } ``` -------------------------------- ### Configure Retry Strategies with proper-lockfile Source: https://context7.com/moxystudio/node-proper-lockfile/llms.txt Illustrates how to configure automatic retries for lock acquisition failures in proper-lockfile. This includes simple retry counts and advanced configurations with exponential backoff and randomization. ```javascript const lockfile = require('proper-lockfile'); const fs = require('fs'); // Simple retry count async function simpleRetry() { fs.writeFileSync('/tmp/file.txt', 'data'); try { const release = await lockfile.lock('/tmp/file.txt', { retries: 5 // Retry up to 5 times }); await doWork(); await release(); } catch (err) { console.error('Failed after retries:', err); } } // Advanced retry configuration async function advancedRetry() { fs.writeFileSync('/tmp/file.txt', 'data'); const release = await lockfile.lock('/tmp/file.txt', { retries: { retries: 10, // Number of retries factor: 2, // Exponential backoff factor minTimeout: 100, // Start with 100ms maxTimeout: 2000, // Cap at 2s randomize: true // Add randomization to prevent thundering herd } }); await doWork(); await release(); } // Retry until lock acquired async function persistentLock() { fs.writeFileSync('/tmp/file.txt', 'data'); const release = await lockfile.lock('/tmp/file.txt', { retries: { retries: Infinity, minTimeout: 500, maxTimeout: 3000 } }); console.log('Finally got the lock!'); await doWork(); await release(); } ``` -------------------------------- ### Network Filesystem Locking with proper-lockfile (NFS) Source: https://context7.com/moxystudio/node-proper-lockfile/llms.txt Illustrates how to use proper-lockfile for reliable locking on network filesystems like NFS. It configures parameters such as stale timeout and update intervals to handle network latency and potential staleness. ```javascript const lockfile = require('proper-lockfile'); const fs = require('fs'); const path = require('path'); // NFS-mounted directory async function nfsLock() { const nfsPath = '/mnt/nfs-share/data.txt'; // Ensure file exists fs.writeFileSync(nfsPath, 'data'); try { const release = await lockfile.lock(nfsPath, { stale: 20000, // Higher staleness threshold for network latency update: 5000, // More frequent updates retries: { retries: 5, minTimeout: 500, maxTimeout: 3000 } }); console.log('Lock acquired on NFS file'); // Perform operations const content = fs.readFileSync(nfsPath, 'utf8'); fs.writeFileSync(nfsPath, content + '\nmodified'); await release(); console.log('Lock released'); } catch (err) { console.error('NFS lock failed:', err); } } // Cross-machine coordination async function distributedLock() { const sharedFile = '/mnt/shared-storage/lock-target.txt'; fs.writeFileSync(sharedFile, 'shared data'); const machineId = require('os').hostname(); const release = await lockfile.lock(sharedFile, { stale: 30000, update: 10000, retries: { retries: Infinity, minTimeout: 1000, maxTimeout: 5000 }, onCompromised: (err) => { console.error(`${machineId}: Lock compromised!`, err); process.exit(1); } }); console.log(`${machineId}: Acquired distributed lock`); // Critical section await performDistributedOperation(); await release(); console.log(`${machineId}: Released distributed lock`); } ``` -------------------------------- ### Multi-process Coordination with proper-lockfile in Node.js Source: https://context7.com/moxystudio/node-proper-lockfile/llms.txt Demonstrates how to use proper-lockfile to coordinate access to shared resources across multiple Node.js processes, including cluster and child process scenarios. It ensures that only one process can modify a shared file at a time. ```javascript const lockfile = require('proper-lockfile'); const fs = require('fs'); const cluster = require('cluster'); const { fork } = require('child_process'); // Cluster example if (cluster.isMaster) { // Fork worker processes for (let i = 0; i < 4; i++) { cluster.fork(); } } else { // Workers compete for lock async function workerTask() { const file = '/tmp/shared-resource.txt'; try { const release = await lockfile.lock(file, { retries: { retries: 10, minTimeout: 100, maxTimeout: 1000 } }); console.log(`Worker ${process.pid} acquired lock`); // Read, modify, write let data = fs.readFileSync(file, 'utf8'); data += `\nProcessed by ${process.pid}`; fs.writeFileSync(file, data); await new Promise(resolve => setTimeout(resolve, 1000)); await release(); console.log(`Worker ${process.pid} released lock`); } catch (err) { console.error(`Worker ${process.pid} failed:`, err.message); } } workerTask(); } // Child process coordination async function parentProcess() { const file = '/tmp/shared.txt'; fs.writeFileSync(file, 'initial'); // Fork multiple children const children = []; for (let i = 0; i < 3; i++) { children.push(fork('./worker.js')); } // Wait for all children await Promise.all(children.map(child => new Promise(resolve => child.on('exit', resolve)) )); console.log('All workers completed'); console.log(fs.readFileSync(file, 'utf8')); } ``` -------------------------------- ### Release File Lock Synchronously (JavaScript) Source: https://github.com/moxystudio/node-proper-lockfile/blob/master/README.md Illustrates the synchronous method for releasing a file lock using `proper-lockfile.unlockSync`. This function throws an error if the lock cannot be released. Dependencies: 'proper-lockfile'. ```javascript const lockfile = require('proper-lockfile'); try { lockfile.unlockSync('some/file'); console.log('Lock released successfully.'); } catch (e) { console.error('Failed to release lock:', e); } ``` -------------------------------- ### Handle Lock Compromise with proper-lockfile Source: https://context7.com/moxystudio/node-proper-lockfile/llms.txt Shows how to detect and handle scenarios where a lock file becomes compromised, either due to staleness or manual deletion. The 'onCompromised' callback in lockfile.lock allows for custom error handling and cleanup procedures. ```javascript const lockfile = require('proper-lockfile'); const fs = require('fs'); // Custom compromise handler async function handleCompromise() { fs.writeFileSync('/tmp/critical.txt', 'data'); let compromised = false; const release = await lockfile.lock('/tmp/critical.txt', { stale: 5000, update: 2000, onCompromised: (err) => { compromised = true; console.error('CRITICAL: Lock compromised!', err); // Perform cleanup cleanupResources(); // Alert monitoring system alertOps('Lock compromised', err); // Don't exit - handle gracefully } }); // Long-running operation try { await longRunningTask(); } finally { if (!compromised) { await release(); } } } // Simulate compromise by deleting lockfile async function simulateCompromise() { const file = '/tmp/test.txt'; fs.writeFileSync(file, 'data'); const release = await lockfile.lock(file, { stale: 5000, update: 1000, onCompromised: (err) => { console.error('Detected:', err.code); // 'ECOMPROMISED' } }); // Simulate external deletion of lockfile setTimeout(() => { fs.rmdirSync(`${file}.lock`); }, 3000); // Lock will detect compromise on next update await new Promise(resolve => setTimeout(resolve, 6000)); } ``` -------------------------------- ### Promise-based Lock API Source: https://context7.com/moxystudio/node-proper-lockfile/llms.txt Acquires a file lock asynchronously. Returns a promise that resolves with a function to release the lock. Supports options for staleness, retries, and more. ```APIDOC ## POST /lock ### Description Acquires a lock on the specified file asynchronously. The lock is maintained through periodic mtime updates to prevent staleness. The function returns a promise that resolves with a `release` function. ### Method POST ### Endpoint `/lock` ### Parameters #### Path Parameters None #### Query Parameters - **file** (string) - Required - The path to the file or directory to lock. - **options** (object) - Optional - Configuration options for the lock. - **stale** (number) - The maximum time in milliseconds after which a lock is considered stale. - **update** (number) - The interval in milliseconds for updating the lock file's modification time. - **retries** (object) - Configuration for retrying lock acquisition. - **retries** (number) - The number of times to retry acquiring the lock. - **minTimeout** (number) - The minimum time in milliseconds to wait before the first retry. - **maxTimeout** (number) - The maximum time in milliseconds to wait between retries. - **realpath** (boolean) - If true, resolves symlinks before locking. - **onCompromised** (function) - A callback function executed if the lock is compromised. - **lockfilePath** (string) - Specifies a custom path for the lock file. ### Request Body (Not applicable for this method, parameters are passed as arguments) ### Request Example ```javascript const lockfile = require('proper-lockfile'); async function basicLock() { try { const release = await lockfile.lock('/tmp/myfile.txt'); console.log('Lock acquired, doing work...'); await doSomeWork(); await release(); console.log('Lock released'); } catch (err) { console.error('Failed to acquire lock:', err); } } async function advancedLock() { const release = await lockfile.lock('/tmp/myfile.txt', { stale: 15000, update: 5000, retries: { retries: 5, minTimeout: 100, maxTimeout: 1000 }, realpath: true, onCompromised: (err) => { console.error('Lock compromised!', err); process.exit(1); } }); await performCriticalOperation(); await release(); } ``` ### Response #### Success Response (200) - **release** (function) - A function that, when called, releases the acquired lock. ``` -------------------------------- ### Acquire Lock Synchronously with proper-lockfile Source: https://context7.com/moxystudio/node-proper-lockfile/llms.txt Acquires a synchronous lock on a specified file using `proper-lockfile.lockSync`. This function blocks execution until the lock is acquired and returns the release function directly or throws an error. Note that the `retries` option is not supported with the synchronous API, and attempting to use it will result in an `ESYNC` error. ```javascript const lockfile = require('proper-lockfile'); const fs = require('fs'); function syncLock() { fs.writeFileSync('/tmp/syncfile.txt', 'data'); try { // Acquire lock synchronously const release = lockfile.lockSync('/tmp/syncfile.txt', { stale: 10000, realpath: false // Skip realpath resolution }); // Perform synchronous operations console.log('Lock acquired'); const data = fs.readFileSync('/tmp/syncfile.txt', 'utf8'); fs.writeFileSync('/tmp/syncfile.txt', data.toUpperCase()); // Release lock synchronously release(); console.log('Lock released'); } catch (err) { if (err.code === 'ELOCKED') { console.error('File is already locked'); } else if (err.code === 'ESYNC') { console.error('Cannot use retries with sync API'); } else { console.error('Lock error:', err); } } } // Note: retries are not allowed with sync API function invalidSync() { try { lockfile.lockSync('/tmp/file.txt', { retries: 3 // This will throw ESYNC error }); } catch (err) { console.error(err.code); // 'ESYNC' } } ``` -------------------------------- ### Acquire Lock Asynchronously with proper-lockfile Source: https://context7.com/moxystudio/node-proper-lockfile/llms.txt Acquires an asynchronous lock on a specified file using `proper-lockfile`. This function returns a promise that resolves with a release function. It supports various options for staleness, retries, and compromise handling. Lock staleness is managed through periodic mtime updates. ```javascript const lockfile = require('proper-lockfile'); const fs = require('fs'); // Basic usage async function basicLock() { fs.writeFileSync('/tmp/myfile.txt', 'data'); try { const release = await lockfile.lock('/tmp/myfile.txt'); // Perform operations while holding the lock console.log('Lock acquired, doing work...'); await doSomeWork(); // Release the lock await release(); console.log('Lock released'); } catch (err) { if (err.code === 'ELOCKED') { console.error('File is already locked'); } else { console.error('Failed to acquire lock:', err); } } } // With options async function advancedLock() { try { const release = await lockfile.lock('/tmp/myfile.txt', { stale: 15000, // Lock considered stale after 15s update: 5000, // Update mtime every 5s retries: { retries: 5, // Retry 5 times if locked minTimeout: 100, // Start with 100ms wait maxTimeout: 1000 // Max 1s between retries }, realpath: true, // Resolve symlinks onCompromised: (err) => { console.error('Lock compromised!', err); process.exit(1); } }); // Do work await performCriticalOperation(); await release(); } catch (err) { console.error('Lock failed:', err.message); } } // Lock a directory with custom lockfile path async function lockDirectory() { const dirPath = '/tmp/mydir'; fs.mkdirSync(dirPath, { recursive: true }); const release = await lockfile.lock(dirPath, { lockfilePath: `${dirPath}/dir.lock` }); // Work with directory contents fs.writeFileSync(`${dirPath}/data.txt`, 'content'); await release(); } ``` -------------------------------- ### Check File Lock Status Asynchronously (JavaScript) Source: https://github.com/moxystudio/node-proper-lockfile/blob/master/README.md Demonstrates how to check if a file is currently locked and its lock is not stale using `proper-lockfile.check`. This function returns a promise that resolves to a boolean indicating the lock status. Dependencies: 'proper-lockfile'. ```javascript const lockfile = require('proper-lockfile'); lockfile.check('some/file') .then((isLocked) => { // isLocked will be true if 'some/file' is locked, false otherwise }); ``` -------------------------------- ### Check File Lock Status Synchronously (JavaScript) Source: https://github.com/moxystudio/node-proper-lockfile/blob/master/README.md Shows the synchronous way to check a file's lock status using `proper-lockfile.checkSync`. This function returns a boolean indicating if the file is locked and not stale, or throws an error if an issue occurs. Dependencies: 'proper-lockfile'. ```javascript const lockfile = require('proper-lockfile'); try { const isLocked = lockfile.checkSync('some/file'); if (isLocked) { console.log('File is locked.'); } else { console.log('File is not locked.'); } } catch (e) { console.error('Error checking lock:', e); } ``` -------------------------------- ### Synchronous Lock API Source: https://context7.com/moxystudio/node-proper-lockfile/llms.txt Acquires a file lock synchronously, blocking the Node.js event loop until the lock is obtained or an error occurs. Returns a function to release the lock. ```APIDOC ## POST /lockSync ### Description Synchronous version of `lock`. This function blocks until the lock is acquired or an error is thrown. It returns the `release` function directly. ### Method POST ### Endpoint `/lockSync` ### Parameters #### Path Parameters None #### Query Parameters - **file** (string) - Required - The path to the file or directory to lock. - **options** (object) - Optional - Configuration options for the lock. Note: `retries` option is not allowed with the synchronous API and will result in an `ESYNC` error. - **stale** (number) - The maximum time in milliseconds after which a lock is considered stale. - **update** (number) - The interval in milliseconds for updating the lock file's modification time. - **realpath** (boolean) - If true, resolves symlinks before locking. - **lockfilePath** (string) - Specifies a custom path for the lock file. ### Request Body (Not applicable for this method, parameters are passed as arguments) ### Request Example ```javascript const lockfile = require('proper-lockfile'); function syncLock() { try { const release = lockfile.lockSync('/tmp/syncfile.txt', { stale: 10000, realpath: false }); console.log('Lock acquired'); // Perform synchronous operations release(); console.log('Lock released'); } catch (err) { console.error('Lock error:', err); } } // Example of invalid usage with retries function invalidSync() { try { lockfile.lockSync('/tmp/file.txt', { retries: 3 }); } catch (err) { console.error(err.code); // 'ESYNC' } } ``` ### Response #### Success Response (200) - **release** (function) - A function that, when called, releases the acquired lock. #### Error Response (400) - **code** (string) - 'ELOCKED' if the file is already locked. - **code** (string) - 'ESYNC' if the `retries` option is used with `lockSync`. ``` -------------------------------- ### Unlock File Lock Synchronously with proper-lockfile Source: https://context7.com/moxystudio/node-proper-lockfile/llms.txt Provides a synchronous version of the unlock function. It releases a file lock synchronously or throws an error if the lock cannot be released. This can be used as an alternative to the release function returned by lockSync(). It's important to handle potential errors, such as trying to unlock a lock that has not been acquired. ```javascript const lockfile = require('proper-lockfile'); const fs = require('fs'); function syncUnlock() { fs.writeFileSync('/tmp/file.txt', 'data'); // Acquire lock const release = lockfile.lockSync('/tmp/file.txt'); // Do work console.log('Performing operations...'); // Can use either the release function or unlockSync try { lockfile.unlockSync('/tmp/file.txt'); console.log('Unlocked successfully'); } catch (err) { console.error('Unlock failed:', err); } } // Attempting to unlock non-existent lock function unlockNotAcquired() { try { lockfile.unlockSync('/tmp/notlocked.txt'); } catch (err) { console.error(err.code); // 'ENOTACQUIRED' } } ``` -------------------------------- ### Unlock File Lock Asynchronously with proper-lockfile Source: https://context7.com/moxystudio/node-proper-lockfile/llms.txt Manually releases a previously acquired file lock asynchronously. It's recommended to use the release function returned by lock() when available. This function can be useful in scenarios where the release function is not easily accessible, such as in different modules. It handles potential errors like 'ENOTACQUIRED' if the lock is not owned by the current process. ```javascript const lockfile = require('proper-lockfile'); const fs = require('fs'); // Using unlock when release function is not available async function manualUnlock() { fs.writeFileSync('/tmp/myfile.txt', 'data'); await lockfile.lock('/tmp/myfile.txt'); // Do work in a different scope where release function // is not easily accessible await doWorkInDifferentModule(); // Manually unlock try { await lockfile.unlock('/tmp/myfile.txt'); console.log('Unlocked successfully'); } catch (err) { if (err.code === 'ENOTACQUIRED') { console.error('Lock was not owned by this process'); } else { console.error('Unlock failed:', err); } } } // Unlock with custom lockfile path async function unlockCustomPath() { const dirPath = '/tmp/mydir'; await lockfile.lock(dirPath, { lockfilePath: `${dirPath}/dir.lock` }); // Later... await lockfile.unlock(dirPath, { lockfilePath: `${dirPath}/dir.lock` }); } // Error handling async function unlockErrors() { try { await lockfile.unlock('/tmp/never-locked.txt'); } catch (err) { console.error(err.code); // 'ENOTACQUIRED' console.error(err.message); // 'Lock is not acquired/owned by you' } } ``` -------------------------------- ### Check File Lock Status Synchronously with proper-lockfile Source: https://context7.com/moxystudio/node-proper-lockfile/llms.txt Provides a synchronous version of the check function. It returns a boolean indicating whether a file is locked and the lock is not stale, or throws an error. This is useful for synchronous operations where checking the lock status is required before proceeding. Options such as 'stale' and 'realpath' can be configured. ```javascript const lockfile = require('proper-lockfile'); const fs = require('fs'); function syncCheck() { fs.writeFileSync('/tmp/file.txt', 'data'); try { const isLocked = lockfile.checkSync('/tmp/file.txt', { stale: 10000, realpath: false }); if (isLocked) { console.log('File is currently locked'); } else { console.log('File is available'); } } catch (err) { console.error('Check failed:', err); } } // Use in conditional logic function conditionalWrite() { const file = '/tmp/data.txt'; fs.writeFileSync(file, 'initial'); if (!lockfile.checkSync(file)) { const release = lockfile.lockSync(file); fs.appendFileSync(file, '\nmore data'); release(); } } ``` -------------------------------- ### Check File Lock Status Asynchronously with proper-lockfile Source: https://context7.com/moxystudio/node-proper-lockfile/llms.txt Asynchronously checks if a file is currently locked and if the lock is not stale. It returns a promise that resolves to a boolean value indicating the lock status. This function can be used to determine if a file is available before attempting to acquire a lock or to monitor the lock status over time. Options like 'stale' can be provided to define the threshold for considering a lock stale. ```javascript const lockfile = require('proper-lockfile'); const fs = require('fs'); // Basic check async function checkLock() { fs.writeFileSync('/tmp/file.txt', 'data'); const isLocked = await lockfile.check('/tmp/file.txt'); if (isLocked) { console.log('File is locked'); } else { console.log('File is not locked'); } } // Check before acquiring lock async function conditionalLock() { fs.writeFileSync('/tmp/file.txt', 'data'); const isLocked = await lockfile.check('/tmp/file.txt', { stale: 10000 // Check with 10s staleness threshold }); if (!isLocked) { const release = await lockfile.lock('/tmp/file.txt'); // Do work await release(); } else { console.log('Someone else has the lock'); } } // Check with custom lockfile path async function checkCustomPath() { const dirPath = '/tmp/mydir'; fs.mkdirSync(dirPath, { recursive: true }); const isLocked = await lockfile.check(dirPath, { lockfilePath: `${dirPath}/dir.lock`, stale: 15000 }); console.log('Directory locked:', isLocked); } // Continuous monitoring async function monitorLock() { const file = '/tmp/monitored.txt'; fs.writeFileSync(file, 'data'); setInterval(async () => { const isLocked = await lockfile.check(file); console.log(`${new Date().toISOString()}: Locked = ${isLocked}`); }, 1000); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.