2011-09-26 6 views
9

Me pregunto cómo puedo abrir varias conexiones simultáneas usando open-uri? CREO que necesito usar hilos o fibras de alguna forma, pero no estoy seguro.Cómo procesar elementos en una matriz en paralelo usando Ruby (y open-uri)

código

Ejemplo:

def get_doc(url) 
    begin 
    Nokogiri::HTML(open(url).read) 
    rescue Exception => ex 
    puts "Failed at #{Time.now}" 
    puts "Error: #{ex}" 
    end 
end 

array_of_urls_to_process = [......] 

# How can I iterate over items in the array in parallel (instead of one at a time?) 
array_of_urls_to_process.each do |url| 
    x = get_doc(url) 
    do_something(x) 
end 

Respuesta

10

También hay una gema llamada Parallel que es similar al melocotón, pero es activamente actualizado

-1

Hay una gema llamada peach (https://rubygems.org/gems/peach), que le permite hacer esto:

require "peach" 

array_of_urls_to_process.peach do |url| 
    do_something(get_doc(url)) 
end 
+0

La joya es jruby solamente –

7

espero que esto le da una idea:

def do_something(url, secs) 
    sleep secs #just to see a difference 
    puts "Done with: #{url}" 
end 

threads = [] 
urls_ary = ['url1', 'url2', 'url3'] 

urls_ary.each_with_index do |url, i| 
    threads << Thread.new{ do_something(url, i+1) } 
    puts "Out of loop #{i+1}" 
end 
threads.each{|t| t.join} 

Tal vez la creación de un método para Array como:

class Array 
    def thread_each(&block) 
     inject([]){|threads,e| threads << Thread.new{yield(e)}}.each{|t| t.join} 
    end 
end 

[1, 2, 3].thread_each do |i| 
    sleep 4-i #so first one ends later 
    puts "Done with #{i}" 
end 
2
module MultithreadedEach 
    def multithreaded_each 
    each_with_object([]) do |item, threads| 
     threads << Thread.new { yield item } 
    end.each { |thread| thread.join } 
    self 
    end 
end 

Uso:

arr = [1,2,3] 

arr.extend(MultithreadedEach) 

arr.multithreaded_each do |n| 
    puts n # Each block runs in it's own thread 
end 
0

Un método simple usando hilos:

threads = [] 

[1, 2, 3].each do |i| 
    threads << Thread.new { puts i } 
end 

threads.each(&:join) 
Cuestiones relacionadas