为什么节点没有检测到我最近创建的文件

时间:2018-04-03 14:42:27

标签: javascript node.js promise semaphore

我有一个Node.js脚本,它订阅通知服务并在收到推送通知时运行一堆东西。但是,该服务有时会为同一事件发送多个通知,因此为了避免重复工作,我制作了一个基本信号量来阻止其他任务。

问题是Node仍然继续执行,尽管 我看到在磁盘上创建的文件 。我尝试了一些不同的解决方案,但我认为问题来自于我缺乏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);
}

我尝试过的其他事情

  • 在一个单独的函数中创建文件,该函数返回promise,结果相同
  • 使用Sync方法写入文件,但后来我无法链接承诺
  • 创建文件后同步等待,无效

1 个答案:

答案 0 :(得分:1)

无需创建外部文件来维护锁定,您可以执行此类操作,这也可以提高性能(减少I / O选择)。

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处理程序中处理其他事情并释放锁定