tmm1 (owner)

Forks

Revisions

  • c89258 tmm1 Thu Apr 16 16:22:02 -0700 2009
  • 717ded tmm1 Thu Apr 16 14:51:14 -0700 2009
  • a2d61d tmm1 Thu Apr 16 14:49:26 -0700 2009
gist: 96699 Download_button fork
public
Description:
simple EM rpc server
Public Clone URL: git://gist.github.com/96699.git
Embed All Files: show embed
em-rpc-server.rb #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
require 'rubygems'
require 'eventmachine'
require 'socket'
 
module RPCServer
  include EM::P::ObjectProtocol
  def post_init
    @obj = Hash.new
  end
  def receive_object method
    send_object @obj.__send__(*method)
  end
  def unbind
    @obj = nil
  end
end
 
unless defined?(BlankSlate)
  if defined?(BasicObject)
    BlankSlate = BasicObject
  else
    class BlankSlate
      instance_methods.each { |m| undef_method m unless m =~ /^__/ }
    end
  end
end
 
class RPCClient < BlankSlate
  def initialize sock = '/tmp/rpc.sock'
    @sock = UNIXSocket.open(sock)
  end
  def method_missing *meth
    data = Marshal.dump(meth)
    @sock.send([data.respond_to?(:bytesize) ? data.bytesize : data.size, data].pack('Na*'), 0)
    Marshal.load @sock.recv(*@sock.recv(4).unpack('N'))
  end
end
 
class AsyncRPCClient < BlankSlate
  module Handler
    include EM::P::ObjectProtocol
    def post_init
      @queue = []
    end
    attr_reader :queue
    def receive_object obj
      if cb = @queue.shift
        cb.call(obj)
      end
    end
  end
  def initialize sock = '/tmp/rpc.sock'
    @sock = EM.connect sock, Handler
  end
  def method_missing *meth, &blk
    @sock.queue << blk
    @sock.send_object(meth)
  end
end
 
EM.run{
  FileUtils.rm '/tmp/rpc.sock' if File.exists? '/tmp/rpc.sock'
  EM.start_server '/tmp/rpc.sock', RPCServer
 
  # use a thread because the client is blocking
  Thread.new{
    o = RPCClient.new
    o[1] = :a
    o[2] = :b
    o[3] = :c
    p o.keys
    p o.values
  }
 
  o = AsyncRPCClient.new
  o[:A] = 99
  o[:B] = 98
  o[:C] = 97
  o.keys{ |keys| p(keys) }
  o.values{ |vals| p(vals) }
}