Skip to content

Commit

Permalink
asynchron echo client
Browse files Browse the repository at this point in the history
  • Loading branch information
grrrisu committed Jun 24, 2012
1 parent 6a127b4 commit 7d78abf
Show file tree
Hide file tree
Showing 16 changed files with 259 additions and 97 deletions.
35 changes: 0 additions & 35 deletions lib/em-box/client.rb

This file was deleted.

29 changes: 29 additions & 0 deletions lib/em-box/client/agent.rb
@@ -0,0 +1,29 @@
module EMBox

module Client

class Agent < BasicObject

def initialize client
@client = client
end

def think
#$stderr.puts agent.look_around
#$stderr.puts agent.move_to 1, 0
end

def says text
echo("client: #{text}")
end

def method_missing method, *args, &block
$stderr.puts method, args
@client.send_message self, method, *args, &block
end

end

end

end
77 changes: 77 additions & 0 deletions lib/em-box/client/base.rb
@@ -0,0 +1,77 @@
require 'fiber'

require_relative 'server_connection'
#require_relative '../sandbox/sandbox'

module EMBox

module Client

class Base

attr_reader :fiber, :agent, :connection

def initialize
$stderr.puts "agent #{self.class} initialized"
start
end

def start
$stderr.puts 'starting client'
EM.run do
begin
@connection = EM::attach($stdin, ServerConnection)
@connection.client = self

@agent = Agent.new(self) # TODO create specific Agent
#start_agent

EM.add_timer(2) do
EM.stop
end
rescue Exception => e
$stderr.puts e.message
@server.send_object :exception => e.message
EM.stop
end
end
end

def start_agent
@fiber = Fiber.new do
begin
agent.think
rescue Exception => e
$stderr.puts e.message
$stderr.puts *e.backtrace.join("\n")
end
end
@fiber.resume
end

def send_message caller, method, *args, &block
if allowed? caller, method
@connection.send_message method, *args
$stderr.puts Fiber.current
Fiber.yield rescue FiberError
end
end

def allowed? caller, method
true
end

def receive_message object
if object['return_value']
@fiber.resume object['return_value']
else
#raise self.inspect
send object['message'], *object['arguments']
end
end

end

end

end
Expand Up @@ -20,14 +20,10 @@ def post_init
def send_message message, *args
send_object :message => message, :arguments => args
end

def method_missing message, *args, &block
send_message message, *args
end

def receive_object json
$stderr.puts "server sent #{json}"
client.send json['message'], *json['arguments']
def receive_object object
$stderr.puts "server sent #{object}"
client.receive_message object
end

end
Expand Down
42 changes: 42 additions & 0 deletions lib/em-box/client/synchronized_client.rb
@@ -0,0 +1,42 @@
require 'fiber'

require_relative 'base'

require_relative 'server_connection'
#require_relative '../sandbox/sandbox'

module EMBox

module Client

class SynchronizedClient < Base

attr_reader :fiber

def start
@fiber = Fiber.new do
super
end
@fiber.resume
end

def receive_message object
if object['return_value']
@fiber.resume object['return_value']
else
super
end
end

protected

def send_to_connection method, *args
super
Fiber.yield
end

end

end

end
4 changes: 4 additions & 0 deletions lib/em-box/client_connection.rb
Expand Up @@ -21,6 +21,10 @@ def status= status
server.call_start_callback
end
end

def send_status status
send_object :status => status
end

def receive_object json
puts "client sent #{json}"
Expand Down
6 changes: 3 additions & 3 deletions lib/em-box/has_client.rb
Expand Up @@ -8,11 +8,11 @@ def self.included(base)

module InstanceMethods

attr_reader :client_class, :client_file
attr_reader :agent_class, :agent_file

def initialize options
@client_class = options[:client_class]
@client_file = options[:client_file]
@agent_class = options[:agent_class]
@agent_file = options[:agent_file]
end

end
Expand Down
17 changes: 13 additions & 4 deletions lib/em-box/server.rb
Expand Up @@ -3,7 +3,7 @@
require 'rubygems'
require 'eventmachine'

require_relative 'client_connection'
require_relative '../em_box'

module EMBox

Expand All @@ -12,22 +12,31 @@ class Server
attr_reader :agents

def initialize agents = [], options = {}
@agents = agents
@ruby = options[:ruby] || File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name'])
@agents = agents
@client_class = options[:client_class] || EMBox::Client::Base
@ruby = options[:ruby] || File.join(RbConfig::CONFIG['bindir'], RbConfig::CONFIG['ruby_install_name'])
end

def add_agent agent
@agents << agent
end

def broadcast status
@agents.each do |agent|
agent.connection.send_status status
end
end

def call_start_callback
@start_callback.call
end

def start &block
EM.run do
@agents.each do |agent|
cmd = "#{@ruby} -rrubygems -rjson -reventmachine -r#{agent.client_file} -e '#{agent.client_class}.new'"
em_lib = File.expand_path(File.dirname(__FILE__) + '/../em_box.rb')
cmd = "#{@ruby} -rrubygems -rjson -reventmachine -r#{em_lib} -e '#{@client_class}.new(\"#{agent.agent_class}\", \"#{agent.agent_file}\")'"
puts cmd
agent.connection = EM.popen(cmd, ClientConnection)
agent.connection.server = self

Expand Down
6 changes: 4 additions & 2 deletions lib/em_box.rb
Expand Up @@ -4,5 +4,7 @@
require_relative 'em-box/server'
require_relative 'em-box/client_connection'
require_relative 'em-box/has_client'
require_relative 'em-box/server_connection'
require_relative 'em-box/client'
require_relative 'em-box/client/agent'
require_relative 'em-box/client/server_connection'
require_relative 'em-box/client/base'
require_relative 'em-box/client/synchronized_client'
18 changes: 18 additions & 0 deletions spec/example/echo/agent.rb
@@ -0,0 +1,18 @@
module Example
module Echo
class Agent < EMBox::Client::Agent

# used for test without return value
def says text
answer "client: #{text}"
end

# used for test with return value
def think
answer = echo "client is thinking"
echo answer
end

end
end
end
25 changes: 25 additions & 0 deletions spec/example/echo/server.rb
@@ -0,0 +1,25 @@
module Example
module Echo
class Server
include EMBox::HasConnection
include EMBox::HasClient

delegates_to_client :says

# used for test without return value
def answer text
puts "received #{text} from client"
received_message text
EM.stop
end

# used for test with return value
def echo text
puts "received #{text} from client"
received_message text
return "server echo: #{text}"
end

end
end
end
11 changes: 0 additions & 11 deletions spec/example/echo_client.rb

This file was deleted.

15 changes: 0 additions & 15 deletions spec/example/echo_server.rb

This file was deleted.

19 changes: 0 additions & 19 deletions spec/integration/communication_spec.rb

This file was deleted.

0 comments on commit 7d78abf

Please sign in to comment.