只有在没有delete_all的多线程情况下,rake任务中才会出现Rails循环依赖性错误



我正在尝试创建一个rake任务来更新数据。问题是它有点慢,所以我想我会让它多线程来加快速度。问题是,当我在1个线程中运行它时,它很好,但当我在5个线程中执行它时,我有时只会得到

rake aborted!
Circular dependency detected while autoloading constant ClassInfo
/home/Tomer/.rvm/gems/ruby-2.2.2/gems/activesupport-4.2.3/lib/active_support/dependencies.rb:492:in `load_missing_constant'
/home/Tomer/.rvm/gems/ruby-2.2.2/gems/activesupport-4.2.3/lib/active_support/dependencies.rb:184:in `const_missing'
/home/Tomer/.rvm/gems/ruby-2.2.2/gems/activesupport-4.2.3/lib/active_support/dependencies.rb:526:in `load_missing_constant'
/home/Tomer/.rvm/gems/ruby-2.2.2/gems/activesupport-4.2.3/lib/active_support/dependencies.rb:184:in `const_missing'
/home/Tomer/workspace/DrexelRegistrationBackend/app/helpers/html_parse_helper.rb:66:in `block in load_class_from_link'
/home/Tomer/.rvm/gems/ruby-2.2.2/gems/nokogiri-1.6.6.2/lib/nokogiri/xml/node_set.rb:187:in `block in each'
/home/Tomer/.rvm/gems/ruby-2.2.2/gems/nokogiri-1.6.6.2/lib/nokogiri/xml/node_set.rb:186:in `upto'
/home/Tomer/.rvm/gems/ruby-2.2.2/gems/nokogiri-1.6.6.2/lib/nokogiri/xml/node_set.rb:186:in `each'
/home/Tomer/workspace/DrexelRegistrationBackend/app/helpers/html_parse_helper.rb:59:in `load_class_from_link'
/home/Tomer/workspace/DrexelRegistrationBackend/app/helpers/html_parse_helper.rb:43:in `block (3 levels) in load_classes_from_catalog'
/home/Tomer/workspace/DrexelRegistrationBackend/app/helpers/html_parse_helper.rb:42:in `each'
/home/Tomer/workspace/DrexelRegistrationBackend/app/helpers/html_parse_helper.rb:42:in `block (2 levels) in load_classes_from_catalog'

我使用nokogiri,打开一个url和html解析它,然后将它插入我的数据库。奇怪的是,如果我在开头插入ClassInfo.delete_all,错误就会消失,但我不想这么做。我需要检查它是否在我的数据库中,所以我检查它是否存在于这行中,这是我崩溃的地方

myclass = ClassInfo.find_by(class_id: class_id)

它没有连接或其他依赖于它的类这是我的迁移

create_table :class_infos do |t|
      t.text :class_id, index: true
      t.text :subject_code
      t.text :subject
      t.text :course_number
      t.text :title
      t.float :credits_lower_range
      t.float :credits_upper_range
      t.text :description
      t.boolean :writing_intensive
      t.text :college
      t.text :repeat_status
      t.text :prereqs
      t.text :restrictions
      t.text :coreqs
      t.text :term_type
      t.text :student_type
      t.timestamps null: false
    end

这是型号

class ClassInfo < ActiveRecord::Base
end

非常奇怪的是,在它崩溃后,我通常可以立即再次运行rake任务,第二次它运行得很好。非常奇怪的

这主要是我的整个模块从我的rake 调用

require 'open-uri'
module HtmlParseHelper
def self.parse_catalog
    Thread.abort_on_exception=true
    @@threads = Array.new
       load_classes_from_catalog(url_sections)  #an array of 5 arrays contaning urls objects
    @@threads.each { |thr| thr.join }
end

def self.load_classes_from_catalog(urlArr)
    arrs.each{|urlSection|
      @@threads.push(
           Thread.new do
             urlSection.each{|url|                     
load_class_from_link(url[0],url[1],url[2],url[3])
                 }
                 ActiveRecord::Base.connection.close
               end
          )
        }
  end

def self.load_class_from_link(link, term_type, student_type, subject)
    begin
    doc = Nokogiri::HTML(open(link))do |config|
      config.strict.noblanks
    end
    class_id = doc.css('div.courseblock').children[0].text
    drexel_class = ClassInfo.find_by(class_id: class_id)   #where it crashes
    #.....
    drexel_class.save
end
end

https://github.com/rails/rails/commit/112077c255879351edf4530791cc4bcc7bd4005b

最后,是急切的装载把我搞砸了。

我刚刚添加了

Rails.application.eager_load!

到开始,它工作

不幸的是,急切的加载并没有帮助我。我通过在运行多任务之前串行执行的rake任务中首先引用依赖项来"解决"它:

   task do_stuff: [:environment] do 
      b = MyModelThatTriggersCircularDependencies
      b = MyOtherModelThatAlsoMisbehaves
      Rake::Task['my_multitask'].invoke
   end
   multitask my_multitask: CONVERT_TXT_TO_MD

最新更新