@imqueue/rpc
Version:
RPC-like client-service implementation over messaging queue
87 lines • 3.38 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.lock = lock;
/*!
* IMQ-RPC Decorators: lock
*
* Copyright (c) 2018, imqueue.com <support@imqueue.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
const __1 = require("..");
/**
* \@lock() decorator implementation
* Will make all simultaneous similar method calls locked to be resolved with
* the first obtained values. Similarity is identified by a bypassed method
* argument values.
*
* @param {boolean|LockOptions} enabledOrOptions - whether to enable locks or not
* @return {(
* target: any,
* methodName: (string),
* descriptor: TypedPropertyDescriptor<(...args: any[]) => any>
* ) => void}
*/
function lock(enabledOrOptions = true) {
return function (target, methodName, descriptor) {
const enabled = typeof enabledOrOptions === 'boolean'
? enabledOrOptions
: !enabledOrOptions.disabled;
const skipArgs = typeof enabledOrOptions === 'boolean'
? undefined
: enabledOrOptions.skipArgs;
const original = descriptor.value;
const className = typeof target === 'function'
? target.name // static
: target.constructor.name; // dynamic
descriptor.value = async function (...args) {
const withLocks = !parseInt(process.env['DISABLE_LOCKS'] + '') && enabled;
let lock;
let sig = '';
if (withLocks) {
sig = (0, __1.signature)(className, methodName, skipArgs ? args.filter((_, index) => !~skipArgs.indexOf(index)) : args);
lock = await __1.IMQLock.acquire(sig, undefined, {
className,
methodName,
args,
});
if (!__1.IMQLock.locked(sig)) {
return lock;
}
}
try {
// istanbul ignore next
let result = original
? original.apply(this, args)
: undefined;
if (result && result.then &&
typeof result.then === 'function') {
result = await result;
}
if (withLocks) {
__1.IMQLock.release(sig, result);
}
return result;
}
catch (err) {
// istanbul ignore next
if (withLocks) {
__1.IMQLock.release(sig, null, err);
}
// istanbul ignore next
throw err;
}
};
};
}
//# sourceMappingURL=lock.js.map