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.
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