require 'celluloid/io'
class Server
include Celluloid::IO
def initialize(host, port)
@server = TCPServer.new host, port
async.run
end
def run
loop { async.handle_connection @server.accept }
end
def handle_connection(socket)
loop { receive_data socket.readpartial(4096), socket }
end
def receive_data(data, client)
Logger.debug "ServerMock receiving data: #{data}"
client.write data
end
end
class Client
include Celluloid::IO
def initialize(host, port)
@host, @port = host, port
Logger.debug "Starting up..."
@condition = Celluloid::Condition.new
end
def run
@socket = TCPSocket.new(@host, @port)
loop { receive_data @socket.readpartial(4096) }
end
def send_data(data)
@socket.write data
@condition.wait if ARGV[0]
end
def bread
@socket.to_io.readpartial(4096)
end
def read
@socket.readpartial(4096)
end
def receive_data(data)
Logger.debug "[RECV] #{data}"
@condition.signal data
end
end
server = Server.new '127.0.0.1', 5038
client = Client.new '127.0.0.1', 5038
client.async.run
sleep 1 # Wait for the socket to connect
fut1 = client.future.send_data 'password'
puts "Trying a blocking read..."
puts "Read #{client.bread.inspect}"
fut2 = client.future.send_data 'password'
puts "Trying a non-blocking read..."
puts "Read #{client.read.inspect}"
puts "Waiting on future values..."
puts "First: #{fut1.value}"
puts "Second: #{fut2.value}"
Without waiting...
1 ↵ ➭ bundle exec ruby mintest.rb [2.0.0]
D, [2013-04-09T19:01:02.371825 #60242] DEBUG -- : Starting up...
Trying a blocking read...
D, [2013-04-09T19:01:02.373009 #60242] DEBUG -- : ServerMock receiving data: password
Read "password"
Trying a non-blocking read...
D, [2013-04-09T19:01:02.373652 #60242] DEBUG -- : ServerMock receiving data: password
E, [2013-04-09T19:01:02.373996 #60242] ERROR -- : Client crashed!
Celluloid::ConditionError: can't wait unless owner
/Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-0.13.0/lib/celluloid/condition.rb:21:in `block in wait'
/Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-0.13.0/lib/celluloid/condition.rb:18:in `synchronize'
/Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-0.13.0/lib/celluloid/condition.rb:18:in `wait'
/Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-io/Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-0.13.0/lib/celluloid/condition.rb:21:in `block in wait': can't wait unless owner (Celluloid::ConditionError)
from /Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-0.13.0/lib/celluloid/condition.rb:18:in `synchronize'
from /Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-0.13.0/lib/celluloid/condition.rb:18:in `wait'
from /Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-io-0.13.1/lib/celluloid/io/stream.rb:392:in `synchronize'
from /Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-io-0.13.1/lib/celluloid/io/stream.rb:48:in `sysread'
from /Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-io-0.13.1/lib/celluloid/io/stream.rb:134:in `readpartial'
from mintest.rb:50:in `read'
from /Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-0.13.0/lib/celluloid/calls.rb:11:in `public_send'
from /Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-0.13.0/lib/celluloid/calls.rb:11:in `dispatch'
from /Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-0.13.0/lib/celluloid/calls.rb:63:in `dispatch'
from /Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-0.13.0/lib/celluloid/actor.rb:326:in `block in handle_message'
from /Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-0.13.0/lib/celluloid/tasks/task_fiber.rb:28:in `block in initialize'
from (celluloid):0:in `remote procedure call'
from /Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-0.13.0/lib/celluloid/actor.rb:69:in `call'
from /Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-0.13.0/lib/celluloid/legacy.rb:14:in `method_missing'
from mintest.rb:71:in `<main>'
With waiting
{19:01}~/code/ruby_ami:develop ✗
1 ↵ ➭ bundle exec ruby mintest.rb true [2.0.0]
D, [2013-04-09T19:01:08.983555 #60267] DEBUG -- : Starting up...
Trying a blocking read...
D, [2013-04-09T19:01:08.984872 #60267] DEBUG -- : ServerMock receiving data: password
Read "password"
Trying a non-blocking read...
/Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-0.13.0/lib/celluloid/condition.rb:21:in `block in wait': can't wait unless owner (Celluloid::ConditionError)
from /Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-0.13.0/lib/celluloid/condition.rb:18:in `synchronize'
from /Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-0.13.0/lib/celluloid/condition.rb:18:in `wait'
from /Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-io-0.13.1/lib/celluloid/io/stream.rb:392:in `synchronize'
from /Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-io-0.13.1/lib/celluloid/io/stream.rb:48:in `sysread'
from /Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-io-0.13.1/lib/celluloid/io/stream.rb:134:in `readpartial'
from mintest.rb:50:in `read'
from /Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-0.13.0/lib/celluloid/calls.rb:11:in `public_send'
from /Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-0.13.0/lib/celluloid/calls.rb:11:in `dispatch'
from /Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-0.13.0/lib/celluloid/calls.rb:63:in `dispatch'
from /Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-0.13.0/lib/celluloid/actor.rb:326:in `block in handle_message'
from /Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-0.13.0/lib/celluloid/tasks/task_fiber.rb:28:in `block in initialize'
from (celluloid):0:in `remote procedure call'
from /Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-0.13.0/lib/celluloid/actor.rb:69:in `call'
from /Users/ben/code/ruby_ami/vendor/ruby/2.0.0/gems/celluloid-0.13.0/lib/celluloid/legacy.rb:14:in `method_missing'
from mintest.rb:71:in `<main>'
Without waiting...
With waiting