Skip to content

Instantly share code, notes, and snippets.

@ujihisa
Created March 20, 2010 03:44
Show Gist options
  • Select an option

  • Save ujihisa/338464 to your computer and use it in GitHub Desktop.

Select an option

Save ujihisa/338464 to your computer and use it in GitHub Desktop.
require 'drb'
# Forky(enum) {|e| something(e) }
# almost same as
# enum.each {|e| something(e) }
# but each block runs on other processes without using thread.
#
# 1. Forky makes flags
# 2. Forky starts DRb server which only has flags
# 3. Forky runs each process asynchronously which process make the flag true after the process finished
# 4. When all flags became true, this method finishs.
#
# ISSUES:
#
# * `sleep 0.2 # dirty` is obviously dirty and dangerous
# * port should not be fixed in 1234
def Forky(enum)
flags = Array.new(enum.to_a.size, :forky_empty)
def flags.finish?
return false unless all? {|i| i != :forky_empty }
DRb.stop_service
true
end
r, w = IO.pipe
fork do
DRb.start_service 'druby://localhost:1234', flags
w.puts "ready"
w.close
r.close
DRb.thread.join
end
r.gets
w.close
client = DRbObject.new nil, 'druby://localhost:1234'
enum.each_with_index do |e, i|
fork do
client[i] = yield e
end
end
loop do
tmp = client[0..-1]
if client.finish?
return tmp
end
sleep 0.01
end
end
if __FILE__ == $0
t = Time.now
results = Forky(0...10) do |i|
sleep(tmp = rand)
p i
tmp
end
puts "It took #{Time.now - t}sec."
p results
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment