简体   繁体   English

Rails 6 从 Sidekiq Job 获取结果 - 有可能吗?

[英]Rails 6 grab results from Sidekiq Job - is it possible?

I've got Sidekiq job ( SyncProductsWorker ) which fires a class Imports::SynchronizeProducts responsible for a few external API calls.我有 Sidekiq 工作( SyncProductsWorker ),它触发了一个Imports::SynchronizeProducts类,负责一些外部 API 调用。

module Imports
  class SyncProductsWorker
    include Sidekiq::Worker
    sidekiq_options queue: 'imports_sync'

    def perform(list)
      ::Imports::SynchronizeProducts.new(list).call
    end
  end
end

The Imports::SynchronizeProducts class gives an array of monads results with some comments eg Imports::SynchronizeProducts类给出了一个带有一些注释的 monads 结果数组,例如

=> [Failure("999999 Product code is not valid"), Failure(" 8888889 Product code is not valid")]

I would like to catch these results to display them on FE.我想捕捉这些结果以在 FE 上显示它们。 Is it possible to do so?有可能这样做吗? If I do something like:如果我这样做:

def perform(list)
  response = ::Imports::SynchronizeProducts.new(list).call
  response
end

And then inside of the controller:然后在控制器内部:

def create
  response = ::Imports::SyncProductsWorker.perform_async(params[:product_codes])

  render json: { result: response, head: :ok }
end

I'll have some number as a result结果我会有一些数字

=> "df3615e8efc56f8a062ba1c2"

I don't believe what you want is possible.我不相信你想要的是可能的。

https://github.com/mperham/sidekiq/issues/3532 https://github.com/mperham/sidekiq/issues/3532

The return value will be GC'd like any other unused data in a Ruby process.返回值将像 Ruby 进程中的任何其他未使用数据一样被 GC 处理。 Jobs do not have a "result" in Sidekiq and Sidekiq does nothing with the value.乔布斯在 Sidekiq 中没有“结果”,而 Sidekiq 对价值没有任何作用。

You would need some sort of model instead that keeps track of your background tasks.您将需要某种模型来跟踪您的后台任务。 This is off the cuff but should give you an idea.这是即兴的,但应该给你一个想法。

EG例如

# @attr result [Array]
# @attr status [String] Values of 'Pending', 'Error', 'Complete', etc..
class BackgroundTask < ActiveRecord
  attr_accessor :product_codes
  after_create :enqueue
  
  def enqueue
    ::Imports::SyncProductsWorker.perform_async(product_codes, self.id)
  end
end

def perform(list, id)
  response = ::Imports::SynchronizeProducts.new(list).call
  if (response.has_errors?)
    BackgroundTask.find(id).update(status: 'Error', result: response)
  else
    BackgroundTask.find(id).update(status: 'Complete', result: response)
  end
end

Then just use the BackgroundTask model for your frontend display.然后只需将 BackgroundTask 模型用于您的前端显示。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM