Reputation: 12092
I want to put a heavy lifting method into a background job. Rails 5 ActiveJob or the use of Redis. Not sure which one I should use.
Basically there will be an API that uses a gem and to stuff things from that API call to my local database.
Controller:
...
before_action :get_api
def do_later
GetApiJob.perform_later(foo)
# Call foo later
end
def foo
@apis.map do |api|
puts api.title
end
end
private
def get_api
@apis = ShopifyAPI::Product.find(:all)
end
...
GetApiJob:
...
queue_as :default
def perform(a)
a
# Expect to see a list, if any, of api's name
end
...
When I call do_later
it will put foo
into a background job. Doing that sample code, I get:
ActiveJob::SerializationError
Should I be using Sidekiq for this?
Upvotes: 0
Views: 5357
Reputation: 5556
ActiveJob is just a common interface between Rails application and different background job runners. You cannot use ActiveJob alone, you still need to add sidekiq (and Redis) or delayed_job or something else.
ActiveJob does the serialization of passed arguments in your Rails application and then deseriales this on the background job side. But you cannot serialize anything, you can only serialize basic types like Fixnum, String, Float, arrays of those basic values, hashes or ActiveRecord objects. ActiveRecord objects are serialized using GlobalId.
In your case you are passing a collection returned from shopify api client, which is not an ActiveRecord collection and ActiveJob doesn't know how to serialize it.
It will be best if you move api call to the background job itself.
Controller
# No before_action
def do_later
# No arguments, because we are fetching all products
GetApiJob.perform_later
end
GetApiJob
queue_as :default
def perform
# Fetch list of products
products = ShopifyAPI::Product.find(:all)
# Process list of products
end
Upvotes: 3