I've got Sidekiq job (SyncProductsWorker
) which fires a class Imports::SynchronizeProducts
responsible for a few external API calls.
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 e.g.
=> [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. 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"
CodePudding user response:
I don't believe what you want is possible.
https://github.com/mperham/sidekiq/issues/3532
The return value will be GC'd like any other unused data in a Ruby process. Jobs do not have a "result" in Sidekiq and Sidekiq does nothing with the value.
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.