cool.ioをFiberと組みあわせる
valaのGIOのasync関数が良かったので、ruby+cool.ioでも
そういう書き方をやってみた。
#!/usr/bin/env ruby require 'fiber' require 'uri' require 'cool.io' class HTTPRequest def initialize(uri, method=:GET) abort "invalid uri: #{uri}" unless uri.kind_of? URI @method=method @uri=uri end def host_port [@uri.host, @uri.port] end def to_s "#{@method} #{@uri.path} HTTP/1.1\r\n"+ "\r\n"+ "\r\n" end end class FiberLogicSocket < Coolio::TCPSocket attr_accessor :fiber [:on_connect, :on_write_complete, :on_read].each do |m| define_method m do |*args| p m @fiber.resume(*args) # 引数を渡してfiberを再開する end end end if $0==__FILE__ then if ARGV.empty? then puts "usage: $0 url" exit end url=ARGV.shift request=HTTPRequest.new(URI.parse url) so=FiberLogicSocket.connect(*request.host_port) so.fiber=Fiber.new do # resume from on_connect so.write request.to_s # non block Fiber.yield # wait for on_write_complete while true do data=Fiber.yield # wait for on_read p data end end # main loop l=Coolio::Loop.default l.attach so l.run end
valaと同じような感じにするにはもっとがんばって書かないといけなくなるので、
妥協してこんな感じになった。
非同期IOのコールバックに分散して記述することになるロジックをFiberの中に固めるという理屈でございます。