查找与锁定和更新调度相关的一个或两个节点模块
Looking for one or two Node modules related to locking and update scheduling
有些人会认为这太琐碎了,不适合寻找模块,也不适合将其归入leftPad类别,但npm中有很多东西,我觉得这两个需求都涵盖了,所以我很想看看其他人做了什么。我继承了这个代码库,它有这种长时间的更新功能,只需要几个步骤。它有一个自定义的锁定标志,一半设置为过期,但实际上没有过期代码。不管怎样,最重要的是防止更新在其他事情发生时发生。除了有时我们知道我们肯定需要尽快更新,但不是在当前更新的中间。这东西实际上不太管用。所以我正在寻找一两个模块来做两件事:
-
两个不同的长时间运行的函数(用回调调用其他函数)可以使用一个带有过期的锁来确保它们不会踩到对方的
-
一个简单的模块/函数,上面写着"现在执行此函数,或者在完成当前运行后再次运行"。
或者,在这种情况下,处理这两种情况的东西可能真的有意义,尽管根据我的描述,它们之间的关系可能并不明显。
过期是指,如果出现我预计不会导致锁在很长一段时间内无法移除的情况,我们不想永远被卡住。
这里有一个例子:
function update() {
// if we are trading, wait until that is done
// if currently updating, skip it or schedule another one right
// after, but only need one more, not a queue of updates
// make a bunch of callbacks or a promise chain, takes a few seconds
// in some cases we will find that we need to do one more update
// immediately after all of this finishes, but not until the end
}
// ...some other places that want to call update
function trade() {
// trade happens sort of sporadically when the tick event fires
// if we are updating, wait until we are done
// make a bunch of callbacks or a promise chain, takes a few seconds
// at the end we need to call update
// but it can't update if it is already updating
}
var Promise = require('bluebird');
// note using a bluebird type of promise
const tradeQueue = [];
var currentlyTrading = false;
var currentlyUpdating = false;
var pendingUpdate = null;
var queuedUpdatePromiseDetails = null;
// returns a promise that returns void, the promise will return
// when either the currently executing update finishes, or a fresh one
// does
function update() {
var test = Math.floor(Math.random() * 1000);
console.log(test, 'update call');
if (!pendingUpdate) {
pendingUpdate = new Promise(function (resolve, reject) {
queuedUpdatePromiseDetails = { resolve: resolve, reject: reject, test: test };
if (currentlyTrading) {
console.log(test, 'setting update to pending');
} else {
// perform update, in callback call resolve() if no err, otherwise reject(err)
console.log(test, 'running update');
currentlyUpdating = true;
setTimeout(resolve, 100);
}
}).finally(function () {
currentlyUpdating = false;
console.log(test, 'update call complete');
pendingUpdate = null;
queuedUpdatePromiseDetails = null;
runPendingTradeOrUpdate();
});
} else {
console.log(test, 'returning existing update promise', queuedUpdatePromiseDetails.test);
}
return pendingUpdate;
}
// returns a promise that completes when this
// new trade finishes
function trade(param) {
var test = Math.floor(Math.random() * 1000);
console.log(test, 'trade call');
return new Promise(function (resolve, reject) {
if (currentlyTrading || currentlyUpdating) {
console.log(test, 'queued trade')
var newTrade = { param: param, resolve: resolve, reject: reject, test: test };
tradeQueue.push(newTrade);
} else {
currentlyTrading = true;
console.log(test, 'beginning trade run');
// perform trade, in callback call resolve() if no error, otherwise reject(err)
setTimeout(resolve, 100);
}
}).finally(function () {
console.log(test, 'trade call complete');
// note that this bit is run for every single trade
currentlyTrading = false;
runPendingTradeOrUpdate();
});
}
// dequeue next trade and run it
function runPendingTradeOrUpdate() {
if (queuedUpdatePromiseDetails && !currentlyUpdating && !currentlyTrading) {
// perform update, in callback call resolve() if no err, otherwise reject(err)
console.log(queuedUpdatePromiseDetails.test, 'running pending update');
currentlyUpdating = true;
setTimeout(queuedUpdatePromiseDetails.resolve, 100);
} else {
if (tradeQueue.length > 0 && !currentlyTrading) {
var nextTrade = tradeQueue.shift();
console.log(nextTrade.test, 'calling queued trade');
trade(nextTrade.param).then(nextTrade.resolve).catch(nextTrade.reject);
}
}
}
var runRandomly = function () {
setTimeout(function () {
update();
}, Math.floor(Math.random() * 300))
setTimeout(function () {
trade(null);
}, Math.floor(Math.random() * 300))
setTimeout(function () {
runRandomly();
}, Math.floor(Math.random() * 300))
}
runRandomly();
好的,非常感谢你们的帮助。
这就是我决定要做的:我现在或再次创建了一个非常简单的模块,并使用现有的带有maxPending功能的锁,而不是过期时间。
我使用这两个模块的方式与自述文件中的示例完全相同。
相关文章:
- javascript函数,它接受两个输入:一个对象和一个键,并返回对象中该键的相应值
- 在输入字段上有两个函数调用,一个在Blur上,一个不在Angular中
- 一个ajax循环有两个输出错误innerHTML
- 将两个Json提要合并为一个,并按时间排序
- 为什么jQuery文件的函数中有两个参数,但只接收一个参数
- 使用javascript将两个文本框值相加到表中的另一个文本框中
- 当两个单独的单词被放在目标上时,使用Jquery获取一个值
- 为两个ID设置一个变量的正确语法
- webgl在一个正方形上操纵两个纹理
- 一个jsp中有两个操作URL
- javascript测试是否存在两个标志中的任何一个
- Jquery:当两个或多个条件为true时,选择一个元素
- 使用一个表达式将两个变量分配给相同的值
- react-让一个元素返回两个相邻的<tr>标签
- 同一事物的两个函数,一个崩溃,另一个不崩溃,为什么
- 检查来自不同数组的两个元素的一个属性是否相等
- 保存两个模型(属于第三个模型)和一个提交
- 一个具有两个图像按钮的表单在只能按下一个按钮的情况下发送两个按钮值
- 将两个express应用程序封装在一个应用程序中
- 一个Web应用程序上有两个Java脚本