Event::Machine is an event-driven I/O and lightweight concurrency library for Ruby. It provides event-driven I/O using the Reactor pattern.
The reactor is the core of Event::Machine.
All of EM's processing happens in the reactor.
Your application will create code that hooks into the reactor, using timers, socket connections or various other means.
Typically you'll wrap your entire application inside an EM#run
block.
EventMachine.run do EventMachine.start_server ... end
This block won't complete until EM#stop
is called. The
reactor will loop infinitely.
[~/ruby/eventmachine/simple(master)]$ cat timer.rb require 'rubygems' require 'eventmachine' puts "Start" EM.run do puts "Init" EM.add_timer(1) do puts "Quitting" EM.stop_event_loop end end puts "Done"
[~/ruby/eventmachine/simple(master)]$ ruby timer.rb Start Init Quitting Done
[~/ruby/eventmachine/simple(master)]$ cat reactor_running.rb require 'rubygems' require 'eventmachine' puts EM.reactor_running? # false EM.run do puts EM.reactor_running? # true EM.next_tick do puts EM.reactor_running? # true EM.stop end end puts EM.reactor_running? # false
reactor_running?
Tells you whether the EventMachine reactor loop is currently running.
Useful when writing libraries that want to run event-driven code, but may be running in programs that are already event-driven.
In
such cases, if reactor_running?
returns false
,
your code can invoke
run
and run your application code inside the block passed to that
method. If this method returns true, just execute your event-aware
code.
(Object) next_tick(pr = nil, &block)
Schedules a proc for execution immediately after the next "turn" through the reactor core.
[~/ruby/eventmachine/simple(master)]$ cat add_timer_family.rb require "eventmachine" EM.run do EM.add_periodic_timer(1) do puts "Tick..." end EM.add_timer(5) do puts "BOOM" EM.stop_event_loop end end [~/ruby/eventmachine/simple(master)]$ ruby add_timer_family.rb Tick... Tick... Tick... Tick... BOOM
(Object) add_timer(*args, &block)
Adds a one-shot timer to the event loop.
Call it with one or two parameters.
The first parameters is a delay-time expressed in seconds (not milliseconds).
The second parameter, if present, must be an object that responds to :call
.
If 2nd parameter is not given, then you can also simply pass a block to the method call.
This method may be called from the block passed to run
or from any
callback method. It schedules execution of the proc
or block passed
to it, after the passage of an interval of time equal to at least
the number of seconds specified in the first parameter to the call.
add_timer
is a non-blocking method. Callbacks can and will
be called during the interval of time that the timer is in effect.
There is no built-in limit to the number of timers that can be
outstanding at any given time.
(Object) add_periodic_timer(*args, &block)
Adds a periodic timer to the event loop. It takes the same parameters
as the one-shot timer method, add_timer
. This method schedules
execution of the given block repeatedly, at intervals of time at
least as great as the number of seconds given in the first parameter
to the call.
[~/ruby/eventmachine/simple(master)]$ cat next_tick.rb require 'eventmachine' EM.run do EM.add_periodic_timer(1) do puts "Hai" end EM.add_timer(5) do EM.next_tick do EM.stop_event_loop end end end
(Object) next_tick(pr = nil, &block)
Schedules a proc for execution immediately after the next "turn" through the reactor core.
This can be useful for improving memory management and/or application responsiveness, especially when scheduling large amounts of data for writing to a network connection.
This method takes either a single argument (which must be a callable object) or a block.
Parameters:
pr (#call) (defaults to: nil) — A callable object to run
[~/ruby/eventmachine/simple(master)]$ ruby next_tick.rb Hai Hai Hai Hai
EM.defer
is used to push a otherwise blocking operation on an EM internal queue whose jobs are then processed by a thread pool of 20 threads (by default).
You can use EM.defer
with operations which aren’t made to work asynchronously.
[~/ruby/eventmachine/simple(master)]$ cat defer.rb require 'eventmachine' require 'thread' EM.run do EM.add_timer(2) do puts "Main #{Thread.current}" EM.stop_event_loop end EM.defer(proc do puts "Defer #{Thread.current}" end) end
(Object) defer(op = nil, callback = nil, &blk)
[~/ruby/eventmachine/simple(master)]$ ruby defer.rb Defer #<Thread:0x007fd9c3826960> Main #<Thread:0x007fd9c38bcd98>
process.nextTick()
actually does is defer the execution of an action till the next pass around the event loop.