You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rails 6中如何获取并展示指定Sidekiq任务上次成功完成时间

实现方案

Sidekiq 默认不会持久化存储已成功执行的任务记录,官方API本身不提供成功历史查询能力,要获取指定Worker上次成功执行的时间,最稳妥可控的方式是自行持久化执行状态,无需依赖任何第三方插件。


方案1:直接在Worker内埋点(最快实现,适配单Worker场景)

只需要在任务执行成功的节点,把成功时间写入数据库即可,注意要正确利用异常中断逻辑,避免任务报错时误记成功状态:

  1. 先生成存任务执行状态的表迁移:
rails generate model WorkerExecutionRecord worker_class:string:index last_success_at:datetime
rails db:migrate
  1. 给模型加便捷查询方法,修改app/models/worker_execution_record.rb:
class WorkerExecutionRecord < ApplicationRecord
  validates :worker_class, presence: true, uniqueness: true

  def self.last_success_for(worker_class)
    find_by(worker_class: worker_class.name)&.last_success_at
  end
end
  1. 修改现有FetchAllProductsWorker,在所有业务逻辑执行完成后更新记录:
module Imports
  class FetchAllProductsWorker
    include Sidekiq::Worker
    sidekiq_options queue: 'imports_fetch_all', retry: 0

    def perform
      # 原有产品拉取、数据库同步业务逻辑
      # (...)

      # 所有逻辑无异常执行到末尾时,更新上次成功时间
      WorkerExecutionRecord.upsert(
        { worker_class: self.class.name, last_success_at: Time.current },
        unique_by: :worker_class
      )
    end
  end
end

前端需要展示同步状态时,直接调用WorkerExecutionRecord.last_success_for(Imports::FetchAllProductsWorker)即可拿到时间,返回空值说明从来没有成功执行过同步任务。

只要把更新时间的代码放在perform方法最末尾,就不需要额外加异常捕获:前面的业务逻辑只要抛错,代码就不会走到更新步骤,完全不会出现误报成功的问题。


方案2:用Sidekiq服务端中间件统一埋点(更易维护,适合后续扩展)

如果后续其他Worker也需要记录执行状态,可以写Sidekiq服务端中间件统一处理结果记录,不用在每个Worker里重复写逻辑:

  1. 新建中间件文件app/sidekiq/middleware/worker_execution_tracker.rb:
module Sidekiq
  module Middleware
    module Server
      class WorkerExecutionTracker
        def call(worker, job, queue)
          yield
          # 代码走到此处说明任务无异常执行完成
          WorkerExecutionRecord.upsert(
            { worker_class: worker.class.name, last_success_at: Time.current },
            unique_by: :worker_class
          )
        end
      end
    end
  end
end
  1. 在Sidekiq初始化文件config/initializers/sidekiq.rb中注册中间件:
Sidekiq.configure_server do |config|
  config.server_middleware do |chain|
    chain.add Sidekiq::Middleware::Server::WorkerExecutionTracker
  end
end

这种方式不需要修改任何Worker的业务代码,所有Worker执行成功后都会自动记录时间,查询方式和方案1完全一致。


注意事项

  • 如果FetchAllProductsWorker可能被并发触发,建议搭配任务去重配置避免重复执行,防止并发写入导致的时间记录不准确
  • 可以按需扩展WorkerExecutionRecord表字段,比如增加last_failed_at、last_error字段,在任务执行抛错时记录失败原因和时间,方便排查同步问题
  • 功能首次上线时,如果历史上已经有过成功执行的同步任务,可以手动在Rails控制台补写一条记录,避免前端首次加载时无数据展示
  • 不推荐使用第三方Sidekiq统计插件,这类插件大多把历史存在Redis中,既会额外占用内存,查询也不如直接读业务库灵活,对于单Worker状态记录的场景完全没有必要

内容的提问来源于stack exchange,提问作者mr_muscle

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 11:36:21