Reputation: 4139
I'm an EM newbie and writing two codes to compare synchronous and asynchronous IO. I'm using Ruby 1.8.7.
The example for sync IO is:
def pause_then_print(str)
sleep 2
puts str
end
5.times { |i| pause_then_print(i) }
puts "Done"
This works as expected, taking 10+ seconds until termination.
On the other hand, the example for async IO is:
require 'rubygems'
require 'eventmachine'
def pause_then_print(str)
Thread.new do
EM.run do
sleep 2
puts str
end
end
end
EventMachine.run do
EM.add_timer(2.5) do
puts "Done"
EM.stop_event_loop
end
EM.defer(proc do
5.times { |i| pause_then_print(i) }
end)
end
5 numbers are shown in 2.x seconds.
Now I explicitly wrote code that EM event loop to be stopped after 2.5 seconds. But what I want is that the program terminates right after printing out 5 numbers. For doing that, I think EventMachine
should recognize all 5 threads are done, and then stop the event loop.
How can I do that? Also, please correct the async IO example if it can be more natural and expressive.
Thanks in advance.
Upvotes: 0
Views: 177
Reputation: 9598
A few things about your Async code. EM.defer schedules the code to execute on a thread. You're then creating more threads. There isn't much point to doing that when you could just use EM.defer in your creation loop. This has the added benefit that EM will service the threads from it's internal threadpool which should be a bit faster as there is no thread creation overhead. (Just note, the EM threadpool has, I believe, 20 threads in it so you want to stay below that number). Something like the following should work (although I haven't tested it)
require 'rubygems'
require 'eventmachine'
def pause_then_print(str)
sleep 2
puts str
end
EventMachine.run do
EM.add_timer(2.5) do
puts "Done"
EM.stop_event_loop
end
5.times do |i|
EM.defer { pause_then_print(i) }
end
end
In terms of detecting when the work is done, you can have EM.defer
execute a callback when its operation is complete. So, you could have a little bit of code in there that adds the callback when i == 4
, or something similar. See the EM docs for how to add the callback: EM.defer
Upvotes: 1