wisper-sidekiq to ActiveJob for Rails v5.2.0

by mmyoji

1 min read

I'm now working on upgrade rails app to v5.2.0 at work and faced with a little issue about job deserialization.

I thought this was because of Sidekiq or ActiveJob, but I was wrong and fount that was because of wisper-sidekiq gem.

The gem uses Sidekiq's delay method. This is deprecated and I recommend YOU DON'T USE the method. Detail

This delay method serializes complex object like ActiveRecord instance as a huge YAML.

When you pass ActiveRecord instance as an argument for the method chained with delay, the YAML contains ActiveRecord::Attribute::xxx classes.

But Rails v5.2.0 has no more ActiveRecord::Attribute modules and classes, and your ActiveJob worker will crash if the old job was left in the queue.

Then stop using wisper-sidekiq gem and re-write a little code in place of it.

The code is like following:

# lib/wisper/sidekiq_broadcaster.rb

require "wisper"

module Wisper
  class SidekiqBroadcastJob < ::ApplicationJob
    def perform(subscriber, event, args)
      subscriber.constantize.public_send(event, *args)
    end
  end

  class SidekiqBroadcaster
    def broadcast(subscriber, _publihser, event, args)
      SidekiqBroadcastJob.perform_later(subscriber.to_s, event, args)
    end
  end
end


# config/initializers/wisper.rb

require "wisper/sidekiq_broadcaster"

Wisper.configure do |config|
  config.broadcaster :sidekiq, Wisper::SidekiqBroadcaster.new
  config.broadcaster :async,   Wisper::SidekiqBroadcaster.new
end

The point is using ActiveJob not using delay.

You cannot pass Class for ActiveJob.perform argument, then pass the class string.

I thought I'll send a pull-request, but both wisper and sidekiq don't depend on rails then I just leave this text for minority like me.

Owari.