如何最好地排队一个长时间运行的任务

所以我有一个插件会启动 Ansible 来执行 Discourse 安装(我真的很想停止使用 WordPress 来处理安装订单!)。

最初,我使用 fork 来启动它,这在测试中运行正常,但我认为应该用更符合“Discourse 风格”的方式来做。

于是,我创建了一个一次性任务来运行该进程,但它却被这样终止了:

E, [2020-12-16T12:53:39.662683 #3158277] ERROR -- : worker=0 PID:3158425 timeout (61s > 60s), killing

我尝试在类中添加 sidekiq_options queue: 'low',然后也添加到了运行该任务的函数中。

随后,我跳过了让任务运行该进程的步骤,直接在模型中运行:

         Discourse::Utils.execute_command(*instructions)

如果我从 rails c 运行,它能正常工作;但无论我如何运行它(这是在 Ubuntu 开发环境中,通过 ./bin/unicorn 启动的),它都会被终止。

一次性任务是指仅执行一次的任务。看起来你需要的是一个由触发器(例如访问控制器的请求)调度的常规任务。

常规任务的执行时间可以超过 60 秒,因为在正常使用中有些任务确实如此。

好吧,我把它改成了常规作业,尝试用 ./bin/rails s 而不是 ./bin/unicorn 运行,但依然没有成功。

这毫无道理,因为我知道其中许多作业的运行时间都超过一分钟。

您具体是如何运行该任务的?能否贴出相关的 Ruby 代码部分?

那当然!

https://github.com/pfaffman/discourse-pfaffmanager/blob/master/app/jobs/regular/create_droplet.rb

https://github.com/pfaffman/discourse-pfaffmanager/blob/master/app/models/pfaffmanager/server.rb#L150-L172

为什么在 https://github.com/pfaffman/discourse-pfaffmanager/blob/49f7369b1dc0b1c8f63065b14c92ac7ecc3ab2b3/app/models/pfaffmanager/server.rb#L146 中使用

Jobs::CreateDroplet.new.execute(server_id: id)

而不是

Jobs.enqueue(:create_droplet, server_id: id)
```?

这就是为什么我需要提问!因为我只是个“穴居人”。(无意冒犯任何住在洞穴里的人。)

当然,这并没有特别的原因。我只是搞不清楚该怎么调用它!

非常感谢!

……它还在运行!……

非常感谢。这至少花了我几个小时……

下一步:在真正的生产服务器上运行它……