Monday, August 22, 2011

Testing GitHub's embeded gist

#!/usr/bin/env ruby
require 'fiber'
require 'benchmark'
DEBUG=false
class FiberRing
attr_reader :id
def initialize(id)
@id = id
DEBUG and puts "Creating ring #{@id}"
@fiber = Fiber.new do
pass_msg
end
end
def |(nxt)
DEBUG and puts "attaching #{@id} to #{nxt.id}"
@next = nxt
nxt
end
def resume
@fiber.resume
end
def pass_msg
DEBUG and puts "#{@id} pass_msg called"
while msg = msg_in
DEBUG and puts "#{@id} received \"#{msg}\""
msg_out msg
end
end
def msg_in
DEBUG and puts "#{@id} msg_in called"
unless @next.nil?
DEBUG and puts "#{@id} resuming #{@next.id}"
@next.resume
DEBUG and puts "#{@id} returned from #{@next.id}.resume"
end
DEBUG and puts "#{@id} msg_in returning \"#{@id} message\""
"#{@id} message"
end
def msg_out msg
DEBUG and puts "#{@id} msg_out called"
DEBUG and puts "#{@id} calling Fiber.yield(#{msg})"
Fiber.yield msg
end
end
n=ARGV[0].to_i
m=ARGV[1].to_i
tm = Benchmark.measure do
#build chain
f0 = f = FiberRing.new(0)
1.upto(n-1) { |i| f = f | FiberRing.new(i) }
#run chain m times
m.times { |j| DEBUG and puts "--- #{j} ---"; f0.resume }
end
puts "#{n}, #{m}, #{tm}"
view raw fiber_ring.rb hosted with ❤ by GitHub

Bugger! No line numbers. I'll look into that.

Tuesday, August 16, 2011

Syncronous coding style with EventMachine and Fibers

I did this a while ago. I am not really happy with it. As I've said before. Event driven code doesn't bother me. Here is an example.

require 'fiber'
require 'eventmachine'

class AsyncIO < EM::Connection
  include EM::P::LineText2
  def initialize df
    @df = df
  end
  def receive_line line
    @df.succeed line
  end
end

def get_line
  f = Fiber.current
  df = EM::DefaultDeferrable.new
  df.callback { |line| f.resume(line) }
  EM.connect '127.0.0.1', 3000, AsyncIO, df
  return Fiber.yield
end

EM.run {
  Fiber.new {
    line = get_line
    puts line
    EM.stop
  }.resume
}

The truth is you should look at EM::Sychrony. Ilya Grigorik explains in he own Blog, how Fibers can help you write synchronous code while keeping the goodness of AsyncIO (ala EventMachine).

I don't find event driven code to be "callback hell" like Ilya Grigorik does. I find evented code easier to read than synchronous code sometimes. In Synchronous code you have to check every time if it failed and why. That is

if (rc < 0)
with
switch (errno) case EINTR:
code after every network call. In event driven code that stuff is dealt with in the event-loop and you just have to define the error callback once.

Ah well just use Node.js . If JavaScript event driven programming is "to hard" for your delicate sensibilities then explain to me how Millions of Web-monkeys pull it off everyday in the browser.