在自动加载常量时检测到间歇性"循环依赖性"生产中的错误

时间:2015-05-15 10:42:28

标签: ruby-on-rails-4 autoload circular-dependency

我有一个Rails项目,它不时地以不可重现的方式在生产中抛出此异常。一切都在开发和测试中运行良好,显然也在生产中,但ExceptionNotifier每隔几周通过电子邮件向我发送此例外...

我不知道发生了什么,所以我会尽可能多地转储有关我的环境的信息,因为我希望其中的一部分可以帮助排除故障。

  • Ruby 2.1.5
  • Rails 4.2.1
  • 使用常规Ruby解释器(即非JRuby)在Heroku中运行

完整错误是:

"Circular dependency detected while autoloading constant DeferredUpdatesHelper"

DeferredUpdatesHelperlib/deferred_updates_helper.rb中定义的模块,因此:

module DeferredUpdatesHelper
  def self.something_something(params)
  end
end

我无法想到这个模块的依赖关系。它非常简单,据我所知,它需要的是一个名为$ RedisPool的全局变量,因此不确定如何存在循环依赖...

此模块用于我的某个模型:models/user.rb

class User < ActiveRecord::Base
  def self.process_deferred_something
    DeferredUpdatesHelper.something_something(params) do
      # do stuff
    end
  end
end

从ActiveJob调用该方法:

class SomeJob < ActiveJob::Base
  queue_as :default

  def perform
    User.process_deferred_something
  end
end

这是在Sidekiq流程中执行的,它每隔10分钟就会非常愉快地运行,除了偶尔我会得到其中一个......

在任何地方都没有require语句,或者至少在这些提到的文件中都没有......如上所述,在开发中一切都正常。

堆栈追踪:

/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/dependencies.rb:492:in `load_missing_constant'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/dependencies.rb:184:in `const_missing'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/dependencies.rb:526:in `load_missing_constant'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/dependencies.rb:184:in `const_missing'
/app/app/models/user.rb:93:in `process_deferred_something'
/app/app/jobs/some_job.rb:5:in `perform'
/app/vendor/bundle/ruby/2.1.0/gems/activejob-4.2.1/lib/active_job/execution.rb:32:in `block in perform_now'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:117:in `call'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:117:in `call'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:555:in `block (2 levels) in compile'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:505:in `call'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:505:in `call'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:498:in `block (2 levels) in around'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:343:in `call'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:343:in `block (2 levels) in simple'
/app/vendor/bundle/ruby/2.1.0/gems/newrelic_rpm-3.11.2.286/lib/new_relic/agent/instrumentation/active_job.rb:46:in `call'
/app/vendor/bundle/ruby/2.1.0/gems/newrelic_rpm-3.11.2.286/lib/new_relic/agent/instrumentation/active_job.rb:46:in `perform'
/app/vendor/bundle/ruby/2.1.0/gems/newrelic_rpm-3.11.2.286/lib/new_relic/agent/instrumentation/active_job.rb:20:in `block (3 levels) in <top (required)>'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:441:in `instance_exec'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:441:in `block in make_lambda'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:342:in `call'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:342:in `block in simple'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:497:in `call'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:497:in `block in around'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:505:in `call'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:505:in `call'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:498:in `block (2 levels) in around'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:343:in `call'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:343:in `block (2 levels) in simple'
/app/vendor/bundle/ruby/2.1.0/gems/activejob-4.2.1/lib/active_job/logging.rb:23:in `call'
/app/vendor/bundle/ruby/2.1.0/gems/activejob-4.2.1/lib/active_job/logging.rb:23:in `block (4 levels) in <module:Logging>'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/notifications.rb:164:in `block in instrument'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/notifications.rb:164:in `instrument'
/app/vendor/bundle/ruby/2.1.0/gems/activejob-4.2.1/lib/active_job/logging.rb:22:in `block (3 levels) in <module:Logging>'
/app/vendor/bundle/ruby/2.1.0/gems/activejob-4.2.1/lib/active_job/logging.rb:43:in `block in tag_logger'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/tagged_logging.rb:68:in `block in tagged'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/tagged_logging.rb:26:in `tagged'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/tagged_logging.rb:68:in `tagged'
/app/vendor/bundle/ruby/2.1.0/gems/activejob-4.2.1/lib/active_job/logging.rb:43:in `tag_logger'
/app/vendor/bundle/ruby/2.1.0/gems/activejob-4.2.1/lib/active_job/logging.rb:19:in `block (2 levels) in <module:Logging>'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:441:in `instance_exec'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:441:in `block in make_lambda'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:342:in `call'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:342:in `block in simple'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:497:in `call'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:497:in `block in around'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:505:in `call'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:505:in `call'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:92:in `_run_callbacks'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:776:in `_run_perform_callbacks'
/app/vendor/bundle/ruby/2.1.0/gems/activesupport-4.2.1/lib/active_support/callbacks.rb:81:in `run_callbacks'
/app/vendor/bundle/ruby/2.1.0/gems/activejob-4.2.1/lib/active_job/execution.rb:31:in `perform_now'
/app/vendor/bundle/ruby/2.1.0/gems/activejob-4.2.1/lib/active_job/execution.rb:21:in `execute'
/app/vendor/bundle/ruby/2.1.0/gems/activejob-4.2.1/lib/active_job/queue_adapters/sidekiq_adapter.rb:40:in `perform'
/app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.3.3/lib/sidekiq/processor.rb:75:in `execute_job'
/app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.3.3/lib/sidekiq/processor.rb:52:in `block (2 levels) in process'
/app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.3.3/lib/sidekiq/middleware/chain.rb:127:in `block in invoke'
/app/lib/sidekiq_monitoring.rb:46:in `call'
/app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.3.3/lib/sidekiq/middleware/chain.rb:129:in `block in invoke'
/app/vendor/bundle/ruby/2.1.0/gems/newrelic_rpm-3.11.2.286/lib/new_relic/agent/instrumentation/sidekiq.rb:33:in `block in call'
/app/vendor/bundle/ruby/2.1.0/gems/newrelic_rpm-3.11.2.286/lib/new_relic/agent/instrumentation/controller_instrumentation.rb:353:in `perform_action_with_newrelic_trace'
/app/vendor/bundle/ruby/2.1.0/gems/newrelic_rpm-3.11.2.286/lib/new_relic/agent/instrumentation/sidekiq.rb:29:in `call'
/app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.3.3/lib/sidekiq/middleware/chain.rb:129:in `block in invoke'
/app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.3.3/lib/sidekiq/middleware/server/active_record.rb:6:in `call'
/app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.3.3/lib/sidekiq/middleware/chain.rb:129:in `block in invoke'
/app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.3.3/lib/sidekiq/middleware/server/retry_jobs.rb:74:in `call'
/app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.3.3/lib/sidekiq/middleware/chain.rb:129:in `block in invoke'
/app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.3.3/lib/sidekiq/middleware/server/logging.rb:11:in `block in call'
/app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.3.3/lib/sidekiq/logging.rb:24:in `with_context'
/app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.3.3/lib/sidekiq/middleware/server/logging.rb:7:in `call'
/app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.3.3/lib/sidekiq/middleware/chain.rb:129:in `block in invoke'
/app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.3.3/lib/sidekiq/middleware/chain.rb:132:in `call'
/app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.3.3/lib/sidekiq/middleware/chain.rb:132:in `invoke'
/app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.3.3/lib/sidekiq/processor.rb:51:in `block in process'
/app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.3.3/lib/sidekiq/processor.rb:98:in `stats'
/app/vendor/bundle/ruby/2.1.0/gems/sidekiq-3.3.3/lib/sidekiq/processor.rb:50:in `process'
/app/vendor/bundle/ruby/2.1.0/gems/celluloid-0.16.0/lib/celluloid/calls.rb:26:in `public_send'
/app/vendor/bundle/ruby/2.1.0/gems/celluloid-0.16.0/lib/celluloid/calls.rb:26:in `dispatch'
/app/vendor/bundle/ruby/2.1.0/gems/celluloid-0.16.0/lib/celluloid/calls.rb:122:in `dispatch'
/app/vendor/bundle/ruby/2.1.0/gems/celluloid-0.16.0/lib/celluloid/cell.rb:60:in `block in invoke'
/app/vendor/bundle/ruby/2.1.0/gems/celluloid-0.16.0/lib/celluloid/cell.rb:71:in `block in task'
/app/vendor/bundle/ruby/2.1.0/gems/celluloid-0.16.0/lib/celluloid/actor.rb:357:in `block in task'
/app/vendor/bundle/ruby/2.1.0/gems/celluloid-0.16.0/lib/celluloid/tasks.rb:57:in `block in initialize'
/app/vendor/bundle/ruby/2.1.0/gems/celluloid-0.16.0/lib/celluloid/tasks/task_fiber.rb:15:in `block in create'

知道可能会发生什么,或者我如何解决它?

1 个答案:

答案 0 :(得分:3)

循环依赖性错误听起来像是一个多线程问题。

您可以尝试将lib添加到eager_load_paths,如下所示:

config.eager_load_paths += ["#{config.root}/lib"]

虽然生产环境中的应用程序默认加载config.eager_load!,但lib不是包含的路径。您可以通过在控制台中运行eager_load_paths来检查Rails.configuration.eager_load_paths中包含的内容。

不确定这是否能解决您的问题,但这是我唯一想到的问题。此外,如果您现在已设法解决您的问题,我很乐意听到解决方案的最新消息。