[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