Sha256: de6cce90c4f14ca0858b14a26c6b55556bac1d446a8a573de923a39838feae68

Contents?: true

Size: 1.22 KB

Versions: 2

Compression:

Stored size: 1.22 KB

Contents

#!/usr/bin/env ruby

require 'socket'
require 'fiber'

# The full implementation is given here, in order to show all the parts. A simpler implementation is given below.
class Reactor
  def initialize
    @readable = {}
    @writable = {}
  end

  def run
    while @readable.any? or @writable.any?
      readable, writable = IO.select(@readable.keys, @writable.keys, [])

      readable.each do |io|
        @readable[io].resume
      end

      writable.each do |io|
        @writable[io].resume
      end
    end
  end

  def wait_readable(io)
    @readable[io] = Fiber.current
    Fiber.yield
    @readable.delete(io)

    return yield if block_given?
  end

  def wait_writable(io)
    @writable[io] = Fiber.current
    Fiber.yield
    @writable.delete(io)

    return yield if block_given?
  end
end

server = TCPServer.new('localhost', 9090)
reactor = Reactor.new

Fiber.new do
  loop do
    client = reactor.wait_readable(server) do
      server.accept
    end

    Fiber.new do
      while buffer = reactor.wait_readable(client) {client.gets}
        reactor.wait_writable(client)
        client.puts(buffer)
      end

      client.close
    end.resume
  end
end.resume

reactor.run

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
ruby-prof-1.4.0-x64-mingw32 test/server.rb
ruby-prof-1.4.0 test/server.rb