为什么 Node 没有检测到我最近创建的文件
Why doesn't Node detect my recently created file
我有一个 Node.js 脚本订阅通知服务并在收到推送通知时运行一堆东西。然而,该服务有时会为同一事件发送多个通知,因此为了避免重复工作,我制作了一个基本的信号量来阻止其他任务。
问题是节点仍然继续执行,尽管 我看到磁盘上创建的文件。我已经尝试了几种不同的解决方案,但我认为问题出在我对 JS 执行模型缺乏经验,我不知道它是如何工作的,这阻碍了我的解决方案的工作。 我该如何解决这个问题?
const fse = require('fs-extra');
// notification handler callback
function handleRequest(data)
{
try{
var semaphore = fse.readJsonSync(__dirname + '/' + objectId);
console.log('task already running, stopping');
return;
}catch(err){
// semaphore doesn't exist, ok to proceed
console.log('starting new task');
fse.writeJson(__dirname + '/' + objectId, {objectId: objectId})
.then(stepOne).catch(rejectPromise)
.then(resp => stepTwo(resp, data)).catch(rejectPromise)
.then(resp => stepThree(resp, extra)).catch(rejectPromise)
.then(resp => stepFour(resp, argument)).catch(rejectPromise)
.then(sleep(20000))
.then(resp => releaseLock(objectId))
.catch(resp => rejectionHandler(resp);
}
}
function releaseLock(objectId)
{
return fse.remove(__dirname + '/' + objectId);
}
我尝试过的其他东西
- 在单独的函数中创建文件,returns 承诺,结果相同
- 使用 Sync 方法写入文件,但我无法链接 promises
- 创建文件后同步等待,无效
不需要创建外部文件来维护锁,你可以这样做,这也会给你带来性能提升( less I/O opts)。
const fse = require('fs-extra');
// notification handler callback
class NamedLocks {
constructor() {
this._pid = {};
}
acquire(pid) {
if (this._pid[pid]) {
// process is locked
// handle it
return Promise.reject();
}
this._pid[pid] = true;
return Promise.resolve();
}
release(pid) {
delete this._pid[pid];
}
}
const userLocks = new NamedLocks();
function handleRequest(data) {
userLocks.acquire(objectId)
.then(() => {
// semaphore doesn't exist, ok to proceed
console.log('starting new task');
fse.writeJson(__dirname + '/' + objectId, { objectId: objectId })
.then(stepOne).catch(rejectPromise)
.then(resp => stepTwo(resp, data)).catch(rejectPromise)
.then(resp => stepThree(resp, extra)).catch(rejectPromise)
.then(resp => stepFour(resp, argument)).catch(rejectPromise)
.then(sleep(20000))
.then(resp => userLocks.release(objectId))
.catch(resp => rejectionHandler(resp))
}).catch(() => {
// handle lock exist condition here
});
};
在这里,您基本上是请求一个锁,如果锁存在,则在 catch 处理程序中处理它,否则执行您的操作并释放锁
我有一个 Node.js 脚本订阅通知服务并在收到推送通知时运行一堆东西。然而,该服务有时会为同一事件发送多个通知,因此为了避免重复工作,我制作了一个基本的信号量来阻止其他任务。
问题是节点仍然继续执行,尽管 我看到磁盘上创建的文件。我已经尝试了几种不同的解决方案,但我认为问题出在我对 JS 执行模型缺乏经验,我不知道它是如何工作的,这阻碍了我的解决方案的工作。 我该如何解决这个问题?
const fse = require('fs-extra');
// notification handler callback
function handleRequest(data)
{
try{
var semaphore = fse.readJsonSync(__dirname + '/' + objectId);
console.log('task already running, stopping');
return;
}catch(err){
// semaphore doesn't exist, ok to proceed
console.log('starting new task');
fse.writeJson(__dirname + '/' + objectId, {objectId: objectId})
.then(stepOne).catch(rejectPromise)
.then(resp => stepTwo(resp, data)).catch(rejectPromise)
.then(resp => stepThree(resp, extra)).catch(rejectPromise)
.then(resp => stepFour(resp, argument)).catch(rejectPromise)
.then(sleep(20000))
.then(resp => releaseLock(objectId))
.catch(resp => rejectionHandler(resp);
}
}
function releaseLock(objectId)
{
return fse.remove(__dirname + '/' + objectId);
}
我尝试过的其他东西
- 在单独的函数中创建文件,returns 承诺,结果相同
- 使用 Sync 方法写入文件,但我无法链接 promises
- 创建文件后同步等待,无效
不需要创建外部文件来维护锁,你可以这样做,这也会给你带来性能提升( less I/O opts)。
const fse = require('fs-extra');
// notification handler callback
class NamedLocks {
constructor() {
this._pid = {};
}
acquire(pid) {
if (this._pid[pid]) {
// process is locked
// handle it
return Promise.reject();
}
this._pid[pid] = true;
return Promise.resolve();
}
release(pid) {
delete this._pid[pid];
}
}
const userLocks = new NamedLocks();
function handleRequest(data) {
userLocks.acquire(objectId)
.then(() => {
// semaphore doesn't exist, ok to proceed
console.log('starting new task');
fse.writeJson(__dirname + '/' + objectId, { objectId: objectId })
.then(stepOne).catch(rejectPromise)
.then(resp => stepTwo(resp, data)).catch(rejectPromise)
.then(resp => stepThree(resp, extra)).catch(rejectPromise)
.then(resp => stepFour(resp, argument)).catch(rejectPromise)
.then(sleep(20000))
.then(resp => userLocks.release(objectId))
.catch(resp => rejectionHandler(resp))
}).catch(() => {
// handle lock exist condition here
});
};
在这里,您基本上是请求一个锁,如果锁存在,则在 catch 处理程序中处理它,否则执行您的操作并释放锁