Search code examples
ruby-on-railssidekiqrails-activejob

Rails production server config.cache_classes = true does not reload custom service classes correctly for active job


I'm using Active Job with sidekiq adapter in Rails 6.1.3.2

Strangely, custom service singleton methods are lost when they're called in Active Job.

notify_message_event_job.rb

module Chats
  class NotifyMessageEventJob < ApplicationJob
    queue_as: default

    def perform(message:, event:)
      Rails.logger.info(PushNotification::Service.name)
      Rails.logger.info(PushNotification::Service.singleton_methods.inspect)
      PushNotification::Service.create(
        user: message.user,
        notification: message.content
      )
    end
  end
end

lib/push_notification/service.rb

module PushNotification
  class Service
    class << self
      def create(user:, notification:)
        // 
      end
    end
  end
end

The following line:

NotifyMessageEventJob.perform_now(message: message, event: event)

produces the following error:

[ActiveJob] [Chats::NotifyMessageEventJob] [b1d934c8-afe0-44a0-bc22-44d40eea7d3d] Performing Chats::NotifyMessageEventJob (Job ID: b1d934c8-afe0-44a0-bc22-44d40eea7d3d) from Sidekiq(default) enqueued at with arguments: {:message=>#<GlobalID:0x00007fe5bc4f6b00 @uri=#<URI::GID gid://interview-server/ChatMessage/156>>, :event=>"NEW_MESSAGE"}

[ActiveJob] [Chats::NotifyMessageEventJob] [b1d934c8-afe0-44a0-bc22-44d40eea7d3d] PushNotification::Service

[ActiveJob] [Chats::NotifyMessageEventJob] [b1d934c8-afe0-44a0-bc22-44d40eea7d3d] [:yaml_tag]

[ActiveJob] [Chats::NotifyMessageEventJob] [b1d934c8-afe0-44a0-bc22-44d40eea7d3d] Error performing Chats::NotifyMessageEventJob (Job ID: b1d934c8-afe0-44a0-bc22-44d40eea7d3d) from Sidekiq(default) in 40.9ms: NoMethodError (undefined method `create' for PushNotification::Service:Class):

As you can see in the log, class PushNotification::Service is correctly loaded, but there is only yaml_tag method.

When I run the following method in rails console:

2.7.3 :001 > PushNotification::Service.singleton_methods

I get:

=> [:create, :ios_app_name, :config, :create_apnsp8_app, :create_apns2_app, :create_android_app, :create_ios_apps, :flush, :notification_enabled?, :create_gcm_notification, :create_apn_notification, :android_app_name, :yaml_tag]

RSpec tests are also passed. I get this error in production server. What's the reason? I'm pulling out of my hair.

UPDATE

I found out that if I set config.cache_classes = false, the code will proceed without any problem.

However, as soon as I reset config.cache_classes = true, the same error will happen again. Of course, I restart production rails server every time I change my code.

I deleted the entire source code, rebooted the server. Pull the code again and restarted rails, but the problem does not disappear.

Any suggestion will be appreciated.


Solution

  • Seemed like it was an issue with zeitwerk autoloading mode which was introduced as default in Rails 6

    I temporarily opted out in config/environments/production.rb:

    config.load_defaults 6.1
    config.autoloader = :classic