EventMachine: The Speed Demon

86
EVENTMACHINE the speed demon Aman Gupta @tmm1

description

EventMachine presentation from RailsConf 2010

Transcript of EventMachine: The Speed Demon

Page 1: EventMachine: The Speed Demon

EVENTMACHINEthe speed demon

Aman Gupta@tmm1

Page 2: EventMachine: The Speed Demon

telnet 10.10.25.42 1337http://gist.github.com/329682

Page 3: EventMachine: The Speed Demon

require 'rubygems'require 'eventmachine'

EM.run{

Page 4: EventMachine: The Speed Demon

EM.run starts the reactor

Page 5: EventMachine: The Speed Demon

Vattenfall (flickr)

Page 6: EventMachine: The Speed Demon

EM.run takes over your process

Page 7: EventMachine: The Speed Demon

EM.run does not return(until you call EM.stop)

Page 8: EventMachine: The Speed Demon

EM.run{ puts 'reactor started!'}puts "this won't happen"

Page 9: EventMachine: The Speed Demon

EM.run{ puts 'reactor started!' EM.stop}puts 'this will happen'

Page 10: EventMachine: The Speed Demon

EM.run starts the reactor

Page 11: EventMachine: The Speed Demon

EM.run starts the reactor

...reactor?

Page 12: EventMachine: The Speed Demon

A reactor reacts to events

Page 13: EventMachine: The Speed Demon

missjdub (flickr)

Page 14: EventMachine: The Speed Demon

A reactor is a single-threaded while loop

(called the “reactor loop”)

Page 15: EventMachine: The Speed Demon

while reactor_running? expired_timers.each{ |timer| timer.process } new_network_io.each{ |io| io.process }end

Page 16: EventMachine: The Speed Demon

while reactor_running? sleep(100) 100_000.times{} while !do_check end # reactor loop is blocked!end

Page 17: EventMachine: The Speed Demon

neoporcupine (flickr)

Page 18: EventMachine: The Speed Demon

The reactor takes over your ruby process

Page 19: EventMachine: The Speed Demon

The reactor takes over your ruby process

and invokes your callbacks on events

Page 20: EventMachine: The Speed Demon

The reactor takes over your ruby process

and invokes your callbacks on events

...callbacks?

Page 21: EventMachine: The Speed Demon

ret = operation()do_something_with(ret)

Page 22: EventMachine: The Speed Demon

ret = operation()do_something_with(ret)

operation{ |ret| do_something_with(ret) }

vs

Page 23: EventMachine: The Speed Demon
Page 24: EventMachine: The Speed Demon
Page 25: EventMachine: The Speed Demon

puts(1)1.times{ puts(2) }puts(3)

Page 26: EventMachine: The Speed Demon

puts(1)1.times{ puts(2) }puts(3)

puts(1)operation{ puts(3) }puts(2)

vs

Page 27: EventMachine: The Speed Demon
Page 28: EventMachine: The Speed Demon

url = db.find_urlresponse = http.get(url)email.send(response)puts 'email sent'

Page 29: EventMachine: The Speed Demon

url = db.find_urlresponse = http.get(url)email.send(response)puts 'email sent'

db.find_url{ |url| http.get(url){ |response| email.send(response){ puts 'email sent' } }}

vs

Page 30: EventMachine: The Speed Demon

Balakov (flickr)

Page 31: EventMachine: The Speed Demon

EM.start_server('0.0.0.0',1337, ChatClient)

Page 32: EventMachine: The Speed Demon

Channel = EM::Channel.new

Page 33: EventMachine: The Speed Demon

SnaPsi (flickr)

Page 34: EventMachine: The Speed Demon

module ChatClient def post_init @name = "anonymous" @sid = Channel.subscribe do |msg| send_msg(msg) end

send_header send_prompt

Channel << "#{@name} has joined." endend

Page 35: EventMachine: The Speed Demon

module ChatClient def post_init @name = "anonymous" @sid = Channel.subscribe do |msg| send_msg(msg) end

send_header send_prompt

Channel << "#{@name} has joined." endend

Page 36: EventMachine: The Speed Demon

module ChatClient def post_init @name = "anonymous" @sid = Channel.subscribe do |msg| send_msg(msg) end

send_header send_prompt

Channel << "#{@name} has joined." endend

Page 37: EventMachine: The Speed Demon

module ChatClient def post_init @name = "anonymous" @sid = Channel.subscribe do |msg| send_msg(msg) end

send_header send_prompt

Channel << "#{@name} has joined." endend

Page 38: EventMachine: The Speed Demon

module ChatClient def post_init @name = "anonymous" @sid = Channel.subscribe do |msg| send_msg(msg) end

send_header send_prompt

Channel << "#{@name} has joined." endend

Page 39: EventMachine: The Speed Demon

module ChatClient def unbind Channel.unsubscribe(@sid) Channel << "#{@name} has left." endend

Page 40: EventMachine: The Speed Demon

module ChatClient def receive_data data @buf ||= '' @buf << data

while line = @buf.slice!(/(.+)\r?\n/) # ... end endend

Page 41: EventMachine: The Speed Demon

module ChatClient def receive_data data @buf ||= '' @buf << data

while line = @buf.slice!(/(.+)\r?\n/) # ... end endend

...@buf?

Page 42: EventMachine: The Speed Demon

rachel_thecat (flickr)

Page 43: EventMachine: The Speed Demon

send_data(“hello”)send_data(“world”)

receive_data(“he”)receive_data(“llowo”)receive_data(“rld”)

network

Page 44: EventMachine: The Speed Demon

while line = @buf.slice!(/(.+)\r?\n/) # ...end

Page 45: EventMachine: The Speed Demon

brain_blogger (flickr)

Page 46: EventMachine: The Speed Demon

if line =~ %r|^/me (.+)| Channel << "#{@name} #{$1.strip}"

Page 47: EventMachine: The Speed Demon

elsif line =~ %r|^/nick (.+)| new_name = $1.strip[0..12] Channel << "#{@name} is #{new_name}" @name = new_name

Page 48: EventMachine: The Speed Demon

elsif line =~ %r|^/quit| close_connection_after_writing

Page 49: EventMachine: The Speed Demon

elsif line =~ %r|^/say (.+)| SayQueue.push "#{@name} said #{$1.strip}"

Page 50: EventMachine: The Speed Demon

else Channel << "#{@name}: #{line}"end

Page 51: EventMachine: The Speed Demon

SayQueue = EM::Queue.new

Page 52: EventMachine: The Speed Demon

thowi (flickr)

Page 53: EventMachine: The Speed Demon

q = EM::Queue.newq.pop{ |item| use(item) }

Page 54: EventMachine: The Speed Demon

# process jobs by invoking `say`processor = proc{ |msg| EM.system("say", msg) do |out, status| # subprocess complete, pop another SayQueue.pop(&processor) end}

# pop the first item off the queueSayQueue.pop(&processor)

Page 55: EventMachine: The Speed Demon

# process jobs by invoking `say`processor = proc{ |msg| EM.system("say", msg) do |out, status| # subprocess complete, pop another SayQueue.pop(&processor) end}

# pop the first item off the queueSayQueue.pop(&processor)

Page 56: EventMachine: The Speed Demon

rtomazela (flickr)

Page 57: EventMachine: The Speed Demon

# process jobs by invoking `say`processor = proc{ |msg| EM.system("say", msg) do |out, status| # subprocess complete, pop another SayQueue.pop(&processor) end}

# kick off the “recursive” procSayQueue.pop(&processor)

Page 58: EventMachine: The Speed Demon

EM.system('ls'){ |output,status| if status.exitstatus == 0 puts output end}

Page 59: EventMachine: The Speed Demon

EM.system('ls'){ |output,status| if status.exitstatus == 0 puts output end}

EM.popen 'ls', LsHandler

Page 60: EventMachine: The Speed Demon

steve.grosbois (flickr)

Page 61: EventMachine: The Speed Demon

EM::PeriodicTimer.new(90) do Channel << "The time is #{Time.now}"end

Page 62: EventMachine: The Speed Demon

tveskov (flickr)

Page 63: EventMachine: The Speed Demon

TwitterStream.new(%w[ railsconf eventmachine]) do |tweet| name = tweet[:user][:screen_name] msg = tweet[:text] Channel << "@#{name}: #{msg}"end

Page 64: EventMachine: The Speed Demon

# gem install em-http-requestrequire 'em-http'

http = EM::HttpRequest.new( "http://stream.twitter.com/" + "filter.json?track=#{tags.join(',')}").get( :head => { 'authorization' => [user, pass] })

Page 65: EventMachine: The Speed Demon

# gem install yajl-rubyrequire 'yajl'

parser = Yajl::Parser.newparser.on_parse_complete = blkhttp.stream do |data| parser << dataend

Page 66: EventMachine: The Speed Demon

So what is EventMachine?

Page 67: EventMachine: The Speed Demon

EventMachine is a reactor.

Page 68: EventMachine: The Speed Demon

Vattenfall (flickr)

Page 69: EventMachine: The Speed Demon

EventMachine is single threaded.

Page 70: EventMachine: The Speed Demon

westpark (flickr)

Page 71: EventMachine: The Speed Demon

EventMachine is a while loop.

Page 72: EventMachine: The Speed Demon

gnislew (flickr)

Page 73: EventMachine: The Speed Demon

EventMachine is all about concurrency.

Page 74: EventMachine: The Speed Demon
Page 75: EventMachine: The Speed Demon

meophamman (flickr)

Page 76: EventMachine: The Speed Demon

pascal.charest (flickr)

Page 77: EventMachine: The Speed Demon

EventMachine is for building web services.

Page 78: EventMachine: The Speed Demon
Page 79: EventMachine: The Speed Demon

$ gem install eventmachine

Page 80: EventMachine: The Speed Demon

$ gem install eventmachine

rubinius

Page 81: EventMachine: The Speed Demon

$ gem install eventmachine

rubiniusjruby

Page 82: EventMachine: The Speed Demon

$ gem install eventmachine

rubiniusjruby

mri 1.8

Page 83: EventMachine: The Speed Demon

$ gem install eventmachine

rubiniusjruby

mri 1.8yarv 1.9

Page 84: EventMachine: The Speed Demon

Code: http://github.com/eventmachine/eventmachineGroup: http://groups.google.com/group/eventmachineRDoc: http://eventmachine.rubyforge.orgIRC: #eventmachine on irc.freenode.net

Page 86: EventMachine: The Speed Demon

QUESTIONS?Aman Gupta

@tmm1http://scribd.com/tmm1