RuntimeError(在自动加载常量应用程序多线程时检测到循环依赖性

时间:2014-12-16 23:52:01

标签: ruby ruby-on-rails-4

我收到此错误: RuntimeError(在自动加载常量应用程序时检测到循环依赖性

当我多线程时。这是我的代码如下。为什么会这样? 我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。 对Nokogiri :: HTML(open())的调用是一个同步阻塞调用,返回需要1秒,我有100,000多个页面要访问,所以我试图运行几个线程来克服这个问题。有没有更好的方法呢?

class ToolsController < ApplicationController

def getWebsites
    t1=Thread.new{func1()}
    t2=Thread.new{func1()}
    t3=Thread.new{func1()}
    t4=Thread.new{func1()}
    t5=Thread.new{func1()}
    t6=Thread.new{func1()}
    t1.join
    t2.join
    t3.join
    t4.join
    t5.join
    t6.join
end

def func1
    puts Thread.current
    apps = Apps.order("RANDOM()").where("apps.website IS NULL").take(1)
    while apps.size == 1  do
        app = apps[0]
        puts app.name
        puts app.iTunes
        doc = Nokogiri::HTML(open(app.iTunes))
        array = doc.css('div.app-links a').map { |link| 
            url = link['href'] 
            url = Domainatrix.parse(url)
            url.domain + "." + url.public_suffix
        }
        array.uniq!
        if (array.size > 0)
            app.website = array.join(', ')
            puts app.website
        else
            app.website = "NONE"
        end
        app.save
        apps = Apps.order("RANDOM()").where("apps.website IS NULL").take(1)
    end 
end


end

1 个答案:

答案 0 :(得分:8)

“require”不是线程安全的

更改您的方法,以便在线程开始之前完成所有“必需”的操作。

例如:

def get_websites
    # values = Apps.all # try uncommenting this line if a second-try is required

    ar = Apps.where("apps.website IS NULL")

    t1 = Thread.new{ func1(ar) }
    t2 = Thread.new{ func1(ar) }

    t1.join
    t2.join
end

def func1( ar )
    apps = ar.order("RANDOM()").limit(1)

    while (apps.size == 1)
      puts Thread.current
    end 
end

但有人指出,不建议您在控制器中进行多线程处理。