Name
global.SelfCleaningMutex
Description
API to Acquire a database-based, system-wide, self-cleaning, named mutex & Release the mutex after use This is appropriate for a Mutex that protects an arbitrary resource with an unpredictable name (e.g. containing a sys_id). (Cf. Mutex, which is more appropriate for a Mutex that is being used over and over again.) This is compatible with Mutex, but cleans up after itself in the database. Caveats The self-cleaning mutex is stored system-wide, in the database, so there is a performance cost to using it. therefore do not acquire and release inside a tight loop! The Mutex Name is the scope of the mutex, and can be anything appropriate, though there are conventions in use in some parts of the system, e.g. table name + record sys_id . Status of Interface Evolving, subject to change. // Example usage var MY_MUTEX = <<<--My Self-cleaning Mutex Name + current.sys_id + -->>> ; ... // Easiest, if you have a single function or method that needs to be restricted to one execution at a time // call myFunction(), in this scope, with arguments (myFunctionArgument1, myFunctionArgument2, ...) // myFunction can also be an anonymous function defined inline. var returnValue = SelfCleaningMutex.enterCriticalSection( MY_MUTEX, this, myFunction, myFunctionArgument1, myFunctionArgument2, ... ); // Alternate more complex way, manually create the self-cleaning mutex object var mySCMutex = new SelfCleaningMutex(MY_MUTEX); // optional mySCMutex.setSpinWait(200); // time to wait between attempts, in ms mySCMutex.setMaxSpins(125); // maximum number of times to try // get the mutex, and then enter the critical section // use finally , to make sure that the mutex is always released. if (mySCMutex.get()) try { // enter critical section ... } finally { mySCMutex.release(); }
Script
var SelfCleaningMutex = Class.create();
/*
* Enter the Critical section, as identified by the mutexName
* and execute the specified criticalFunction() with the given arguments
*/
SelfCleaningMutex.enterCriticalSection = function(scMutexName, scope, criticalFunction) {
var mutex = new SelfCleaningMutex('<<<--' + scMutexName + '-->>>');
return mutex.enterCriticalSection.apply(mutex, arguments);
};
/*
* Enter the Critical section, as identified by the mutexName and metricName that will be used in performance graphs
* and execute the specified criticalFunction() with the given arguments
*/
SelfCleaningMutex.enterCriticalSectionRecordInStats = function(scMutexName, metricName, scope, criticalFunction) {
var mutex = new SelfCleaningMutex('<<<--' + scMutexName + '-->>>', metricName);
return mutex.enterCriticalSectionRecordInStats.apply(mutex, arguments);
};
SelfCleaningMutex.prototype = Object.extendsObject(Mutex, {
initialize : function(mutexId, metricName) {
if (metricName === undefined) {
this._mutex = new GlideSelfCleaningMutex(mutexId);
}
else {
this._mutex = new GlideSelfCleaningMutex(mutexId, metricName);
}
// limit our attempt to get a mutex
this.setSpinWait(this._getScriptSpinWaitSetting());
this.setMaxSpins(this._getScriptMaxSpinsSetting());
},
// default spin wait times, 10ms for 100 attempts -- same as Mutex
// properties to override the default values (from Mutex), for SelfCleaningMutex specifically
MUTEX_SPINWAIT_MS: 'com.glide.selfcleaningmutex.script.spinwait',
MUTEX_MAXSPINS: 'com.glide.selfcleaningmutex.script.maxspins',
type: 'SelfCleaningMutex'
});
Sys ID
e617cd109f2020008f88ed93ee4bcc57