【问题标题】:Periodic task with setTimeout in Node.js stopped runningNode.js 中带有 setTimeout 的定期任务停止运行
【发布时间】:2018-05-24 17:31:55
【问题描述】:

在 Node.js 应用程序中,我需要每 10 秒运行一次后台任务(一般意义上的任务)。大多数时候,这个任务是一个简单的轮询另一个 web 服务,并且不时地在那个 web 服务中发生一些变化,后台任务会更新我的应用程序的内部状态。仅供参考,此应用程序在 Openshift 部署中的 Docker 容器中运行。

今天我意识到后台任务已经停止执行。日志文件没有显示任何异常或其他可疑消息。 Openshift pod 的 CPU 和内存消耗看起来很正常。不幸的是,我没有启用 verbose 日志级别,只有 info,而且我的 Linux 技能还不足以进行进程转储并进行分析。

我想知道我在实现此后台任务的方式上是否做错了什么。此外,这是我第一次遇到这种情况(AFAIK),该应用程序已经开发了一年多,应用程序实例有时运行 2 个月或更长时间没有问题。

let pollingActive = true;
let pollingInterval = 10000;

const pollingMethod = () => {
    if (!this.pollingActive) {
        return;
    }

    logger.verbose('Start of synchronization cycle.');
    performSync() // this is the polling and internal state update work
    .then(() => {
        this.pollingHandle = setTimeout(() => { pollingMethod(); },
            this.pollingInterval);
    })
    .catch(err => {
        logger.info('Error while synchronizing.', err);
        this.pollingHandle = setTimeout(() => { pollingMethod(); },
            this.pollingInterval);
    });
};

pollingMethod();

我仔细检查了我的代码,唯一一次 pollingActive 变为 false 是 Node.js 应用程序关闭时,我知道它没有关闭,因为它仍在响应常规 REST API 请求.

知道为什么这个后台任务会停止工作吗?

旁注:我确信有更好的方法可以在 Node.js 或 Docker 容器中执行后台任务,包括让外部 Web 服务通过队列发送更改通知(可能仍需要轮询; -) 但是,由于这个项目正在“退出”,我无法做出重大改变。

【问题讨论】:

  • “我仔细检查了我的代码,唯一一次 pollingActive 变为 true 是......”你的意思是“唯一一次 pollingActive 变为 false"?
  • performSync 怎么样?你确定它调用了它的成功或错误处理程序吗?
  • @DavidKnipe 感谢您指出这个错字。是的,它应该是“假的”。
  • 我再次检查了整个 performSync 逻辑,以检查所有返回路径是否正确返回 Promise。在我看来很好。我现在将打开详细日志记录,以防再次发生这种情况。如果是这样,日志有望提供更好的线索。
  • 你可以在这里发performSync,以防你遗漏了什么。

标签: javascript node.js


【解决方案1】:

这是一个有趣的问题,因为目前,对我来说到底会发生什么仍然是个谜。为此,我们需要更多信息。然而,它确实让我在what NodeJS says about timers 上找到了一些有趣的信息:

不能依赖设置的超时间隔在确切的毫秒数之后执行。这是因为阻塞或保留事件循环的其他执行代码会将超时的执行推回。唯一的保证是超时不会早于声明的超时间隔执行。

显然,他们不保证计时器何时会被触发。不过,就个人而言,如果可能的话,我建议您使用操作系统提供的东西。尝试查看cron,这是一个在操作系统(Linux 等)中安排任务的系统。 This Stackoverflow question 有一些好的指针和链接可以继续阅读。

【讨论】:

  • 我不会担心文档中的那一段。我认为它最终仍应执行该功能。
  • 事件循环没有被完全阻塞,因为应用程序没有被完全阻塞,因为它会及时响应对各种 REST API 控制器的请求。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-12
  • 1970-01-01
  • 2022-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多