在Rails中安排一个ActiveJob

6
我正在制作一个天气API,它将从另一个API获取、处理和保存数据。为了获得每日更新(请求URL信息,获取JSON/XML数据,构建我的数据并将其保存到数据库中),我认为最合适的方法是使用ActiveJob。
我想定期安排工作。我希望有类似于UNIX cron或Java的Spring @Scheduled注释的东西。
我在Stack Overflow上看到了其他关于调度作业的问题(this one),但它们使用外部gem,例如whenever。我一直在寻找一个后端,允许在Rails API中执行作业(Backends),但似乎没有可用的后端允许调度作业。
在Rails框架(版本5)中是否有任何可以实现我正在尝试的功能?或者我必须使用外部gem?
非常感谢您。
编辑 如果对任何人有用,这是工作的模式:
class ImportDailyDataJob < ApplicationJob
  queue_as :default

  def perform(*args)
    # Do something later
  end

  private

  def prepare_request
    # return the request object
  end

  def request_data
    # Get the data from external API.
  end

  def process_data
    # Process the data
  end

  def save_processed_data
    # Saves the data to the database
  end
end

因为只有一种Rails的方式来做这个会很好,所以我点赞了。就个人而言,我已经使用cron作业来运行Rails脚本了。 - Jon
只是为了澄清关于外部 gem 和 ActiveJob 的一些事情:AJ 提供了一个通用接口,可以轻松地将使用 Resque 的相同代码切换到 Sidekiq 等队列适配器。然而,如果没有使用 Rails 核心之外的工具,你不会真正从 AJ 中获得太多好处。 - Glyoko
有人尝试过 active_job 吗? - Aparichith
3个回答

4

这不是真正的调度,但在某些情况下,如果您不需要完全准确的调度,可以模拟它,例如在您的情况下每天运行作业:

class WeatherJob < ApplicationJob
  def perform
    reschedule_job

    do_work
  end

  def do_work
    # ...
  end

  def reschedule_job
    self.class.set(wait: 24.hours).perform_later
  end
end

使用ActiveJob将作业排队以在未来运行应该与DelayedJob或Sidekiq配合使用,但可能不受所有Active Job后端的支持?

1
不错的方法!你的方法使我能够每天执行一次工作,而不需要使用外部gem,但是如何最初运行它呢? - F404
只需在Rails控制台中第一次排队即可 bundle exec rails console - WeatherJob.perform_later 将立即运行,这将使记录再次排队以在24小时后运行。 - house9

1
我认为你应该选择使用sidekiqredis编写一个任务来安排工作。只需安装这两个 gem 并查看它们的文档即可。
gem 'redis-rails'

然后安装Sidekiq

gem 'sidekiq'

谢谢您的回答。由于两个答案都确认了,Rails上没有内置的调度程序。 - F404
不,ActiveJob并不提供redis和sidekiq的所有功能,但它是Rails的核心。你需要先阅读文档,然后才能处理它,但是使用redis和sidekiq将更好地理解它,并且还可以使用ui界面。 - nitanshu verma

1
大多数主要的AJ适配器都具有一些作业调度功能,但有些将该功能分为单独的宝石。例如,对于Resque,有一个单独的resque-scheduler宝石,可以与普通的Resque宝石一起使用。

以下是关于定期作业的内容here's。在进行一些基本设置后,您需要创建一个schedule.yml文件来定义您希望作业何时/如何运行,例如:

# config/initializers/resque_scheduler.rb
Resque.schedule = YAML.load_file('../calendar.yml')

# config/calendar.yml
your_recurring_job:
  cron: "0 0 * * *" # Every day at midnight
  class: "YourJobClass"
  queue: your_queue
  args:
  description: "This job does a thing, daily"

我不知道每个适配器的情况,但通常主要适配器都有类似的姊妹 gem 来提供这种功能。

要明确的是,尽管它使用cron语法,但它并不通过cron。它完全在Redis/Resque内部工作。 - Glyoko
感谢您的解释和提供的链接。我需要调查一下Redis在作业调度程序中的角色,因为两个答案都建议使用外部gem + Redis。但这将是另一个问题的好话题。无论如何,我可能会使用Resque。 - F404

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接