FCF 2.0 development in progress...
> > > >
[News] [Packages API] [Downloads] [Donate to the project] [Contacts]

fcf.NLock.tryLockNamedMutex() function

[SERVER ONLY] fcf.NLock.tryLockNamedMutex(string a_name, function a_cb)
[SERVER ONLY] fcf.NLock.tryLockNamedMutex(string a_name, boolean a_quiet, function a_cb)

Package: fcf-framework-lock

File: fcf-framework-lock:index.js

Available from version: 1.0.6

Locks a named mutex without waiting. If the mutex is already locked, the function fails and the error object contains the unavailable field set to true. If a_quiet is true, then if the mutex is already locked, the function calls the callback with a lock index value of undefined.

Arguments

string a_name
- The mutex name

boolean a_quiet = false
- If true, then if a lock is held that is already locked, the function exits without error, and the value of the a_lock argument in the callback function is undefined. If the value is not set or is false, then if the mutex is already locked, the function will fail with an error object containing an unavailable field equal to true.

function a_cb
- The function of processing the result of the function execution

Function signature: a_cb(Error|undefined a_error, number a_lock)

  • Error|undefined a_error - Error object. If the function was locking on an already locked mutex, then the error object will contain the unavailable property set to true.

  • number a_lock - If successful, contains a lock handle that must be passed to the fcf.NLock.unlockNamedMutex function to unlock the mutex.

Example: Using a function with a_quiet set to false

Below is an example of implementing a critical section using named mutexes. The output to the terminal is made for two instance of the program running simultaneously.

let libLock = require("fcf-framework-lock"); async function main(){ const mutexName = "TestMutexForExample" try { console.log(`PID:${process.pid}: ${new Date().toISOString()}: Wait locking ...`); let lock = await new Promise((a_res, a_rej)=>{ libLock.tryLockNamedMutex(mutexName, (a_error, a_lock)=>{ if (!a_error){ a_res(a_lock); } else { a_rej(a_error); } }); }); console.log(`PID:${process.pid}: ${new Date().toISOString()}: Start of critical section`); await new Promise((a_res, a_rej)=>{ setTimeout(()=>{ a_res(0); }, 1000); }); console.log(`PID:${process.pid}: ${new Date().toISOString()}: End of critical section`); console.log(`PID:${process.pid}: ${new Date().toISOString()}: Release mutex`); await new Promise((a_res, a_rej)=>{ libLock.unlockNamedMutex(lock, (a_error)=>{ if (!a_error){ a_res(); } else { a_rej(a_error); } }); }); } catch(e) { if (e.unavailable) { console.log(`PID:${process.pid}: ${new Date().toISOString()}: Failed to lock the mutex because the mutex is already locked`); } console.log(`PID:${process.pid}: ${new Date().toISOString()}: Error: ${e.message}`); } console.log(`PID:${process.pid}: ${new Date().toISOString()}: Process is exit`); } main();

Output:

PID:11058: 2023-10-21T19:05:18.221Z: Wait locking ... PID:11059: 2023-10-21T19:05:18.222Z: Wait locking ... PID:11058: 2023-10-21T19:05:18.226Z: Start of critical section PID:11059: 2023-10-21T19:05:18.227Z: Failed to lock the mutex because the mutex is already locked PID:11059: 2023-10-21T19:05:18.228Z: Error: Resource temporarily unavailable PID:11059: 2023-10-21T19:05:18.228Z: Process is exit PID:11058: 2023-10-21T19:05:19.228Z: End of critical section PID:11058: 2023-10-21T19:05:19.228Z: Release mutex PID:11058: 2023-10-21T19:05:19.229Z: Process is exit

Example: Using a function with a_quiet set to true

Below is an example of implementing a critical section using named mutexes. The output to the terminal is made for two instance of the program running simultaneously.

let libLock = require("fcf-framework-lock"); async function main(){ const mutexName = "TestMutexForExample" console.log(`PID:${process.pid}: ${new Date().toISOString()}: Wait locking ...`); let lock = await new Promise((a_res, a_rej)=>{ libLock.tryLockNamedMutex(mutexName, true, (a_error, a_lock)=>{ if (!a_error){ a_res(a_lock); } else { a_rej(a_error); } }); }); if (lock) { console.log(`PID:${process.pid}: ${new Date().toISOString()}: Start of critical section`); await new Promise((a_res, a_rej)=>{ setTimeout(()=>{ a_res(0); }, 1000); }); console.log(`PID:${process.pid}: ${new Date().toISOString()}: End of critical section`); console.log(`PID:${process.pid}: ${new Date().toISOString()}: Release mutex`); await new Promise((a_res, a_rej)=>{ libLock.unlockNamedMutex(lock, (a_error)=>{ if (!a_error){ a_res(); } else { a_rej(a_error); } }); }); } else { console.log(`PID:${process.pid}: ${new Date().toISOString()}: Failed to lock the mutex because the mutex is already locked`); } console.log(`PID:${process.pid}: ${new Date().toISOString()}: Process is exit`); } main();

Output:

PID:11000: 2023-10-21T19:03:22.947Z: Wait locking ... PID:11001: 2023-10-21T19:03:22.949Z: Wait locking ... PID:11000: 2023-10-21T19:03:22.952Z: Start of critical section PID:11001: 2023-10-21T19:03:22.954Z: Failed to lock the mutex because the mutex is already locked PID:11001: 2023-10-21T19:03:22.954Z: Process is exit PID:11000: 2023-10-21T19:03:23.954Z: End of critical section PID:11000: 2023-10-21T19:03:23.954Z: Release mutex PID:11000: 2023-10-21T19:03:23.954Z: Process is exit