Rails 生产服务器 config.cache_classes = true 不会为活动作业正确重新加载自定义服务 类
Rails production server config.cache_classes = true does not reload custom service classes correctly for active job
我在 Rails 6.1.3.2
中使用 Active Job 和 sidekiq 适配器
奇怪的是,自定义服务单例方法在 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
下面一行:
NotifyMessageEventJob.perform_now(message: message, event: event)
产生以下错误:
[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):
正如你在日志中看到的,class PushNotification::Service
被正确加载,但是只有 yaml_tag
方法。
当我 运行 在 rails 控制台中使用以下方法时:
2.7.3 :001 > PushNotification::Service.singleton_methods
我得到:
=> [: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 测试也通过了。我在生产服务器中收到此错误。什么原因?我正在拔头发。
更新
我发现如果我设置 config.cache_classes = false
,代码将毫无问题地继续。
但是,我一重新设置config.cache_classes = true
,同样的错误又会发生。当然,每次更改代码时,我都会重新启动生产 rails 服务器。
我删除了整个源代码,重新启动了服务器。再次拉取代码,重启rails,问题并没有消失
如有任何建议,我们将不胜感激。
似乎是 zeitwerk autoloading mode 的问题,它在 Rails 6
中作为默认值引入
我暂时选择退出 config/environments/production.rb:
config.load_defaults 6.1
config.autoloader = :classic
我在 Rails 6.1.3.2
中使用 Active Job 和 sidekiq 适配器奇怪的是,自定义服务单例方法在 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
下面一行:
NotifyMessageEventJob.perform_now(message: message, event: event)
产生以下错误:
[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):
正如你在日志中看到的,class PushNotification::Service
被正确加载,但是只有 yaml_tag
方法。
当我 运行 在 rails 控制台中使用以下方法时:
2.7.3 :001 > PushNotification::Service.singleton_methods
我得到:
=> [: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 测试也通过了。我在生产服务器中收到此错误。什么原因?我正在拔头发。
更新
我发现如果我设置 config.cache_classes = false
,代码将毫无问题地继续。
但是,我一重新设置config.cache_classes = true
,同样的错误又会发生。当然,每次更改代码时,我都会重新启动生产 rails 服务器。
我删除了整个源代码,重新启动了服务器。再次拉取代码,重启rails,问题并没有消失
如有任何建议,我们将不胜感激。
似乎是 zeitwerk autoloading mode 的问题,它在 Rails 6
中作为默认值引入我暂时选择退出 config/environments/production.rb:
config.load_defaults 6.1
config.autoloader = :classic