emdrb 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.txt +5 -2
 - data/lib/emdrb/emdrb.rb +230 -88
 - data/lib/emdrb/version.rb +2 -2
 - data/test/test_emdrb.rb +34 -2
 - metadata +2 -2
 
    
        data/README.txt
    CHANGED
    
    | 
         @@ -12,8 +12,9 @@ available in the Ruby standard library. 
     | 
|
| 
       12 
12 
     | 
    
         | 
| 
       13 
13 
     | 
    
         
             
            This is a simple but working DRb server implementation that uses
         
     | 
| 
       14 
14 
     | 
    
         
             
            EventMachine as its basis, rather than the default implementation that
         
     | 
| 
       15 
     | 
    
         
            -
            uses traditional Ruby sockets.  This should  
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
      
 15 
     | 
    
         
            +
            uses traditional Ruby sockets.  This should at the very least play
         
     | 
| 
      
 16 
     | 
    
         
            +
            better with other programs that have an EventMachine event loop, and
         
     | 
| 
      
 17 
     | 
    
         
            +
            hopefully provide somewhat better scalability.
         
     | 
| 
       17 
18 
     | 
    
         | 
| 
       18 
19 
     | 
    
         
             
            Obviously, this is a quick and dirty release, just to get something
         
     | 
| 
       19 
20 
     | 
    
         
             
            out there, and of course it has a number of limitations.
         
     | 
| 
         @@ -47,6 +48,8 @@ making one with the standard library DRb: 
     | 
|
| 
       47 
48 
     | 
    
         
             
              EMDRb.start_service(URI, TimeServer.new)
         
     | 
| 
       48 
49 
     | 
    
         
             
              EMDRb.thread.join
         
     | 
| 
       49 
50 
     | 
    
         | 
| 
      
 51 
     | 
    
         
            +
            It is also possible to create 
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
       50 
53 
     | 
    
         
             
            == REQUIREMENTS:
         
     | 
| 
       51 
54 
     | 
    
         | 
| 
       52 
55 
     | 
    
         
             
            * Obviously, EMDRb requires EventMachine.
         
     | 
    
        data/lib/emdrb/emdrb.rb
    CHANGED
    
    | 
         @@ -4,7 +4,7 @@ 
     | 
|
| 
       4 
4 
     | 
    
         
             
            # Homepage:: http://emdrb.rubyforge.org/
         
     | 
| 
       5 
5 
     | 
    
         
             
            # License:: GNU General Public License / Ruby License
         
     | 
| 
       6 
6 
     | 
    
         
             
            #
         
     | 
| 
       7 
     | 
    
         
            -
            # $Id: emdrb.rb  
     | 
| 
      
 7 
     | 
    
         
            +
            # $Id: emdrb.rb 28 2009-01-22 05:13:01Z dido $
         
     | 
| 
       8 
8 
     | 
    
         
             
            #
         
     | 
| 
       9 
9 
     | 
    
         
             
            #----------------------------------------------------------------------------
         
     | 
| 
       10 
10 
     | 
    
         
             
            #
         
     | 
| 
         @@ -27,10 +27,78 @@ module EMDRb 
     | 
|
| 
       27 
27 
     | 
    
         
             
              DEFAULT_LOAD_LIMIT = 256 * 102400
         
     | 
| 
       28 
28 
     | 
    
         
             
              DEFAULT_SAFE_LEVEL = 0
         
     | 
| 
       29 
29 
     | 
    
         | 
| 
      
 30 
     | 
    
         
            +
              ##
         
     | 
| 
      
 31 
     | 
    
         
            +
              # Common protocol elements for distributed Ruby, used by both the
         
     | 
| 
      
 32 
     | 
    
         
            +
              # client and server.
         
     | 
| 
      
 33 
     | 
    
         
            +
              #
         
     | 
| 
      
 34 
     | 
    
         
            +
              module DRbProtocolCommon
         
     | 
| 
      
 35 
     | 
    
         
            +
                ##
         
     | 
| 
      
 36 
     | 
    
         
            +
                # This method will dump an object +obj+ using Ruby's marshalling
         
     | 
| 
      
 37 
     | 
    
         
            +
                # capabilities.  It will make a proxy to the object instead if
         
     | 
| 
      
 38 
     | 
    
         
            +
                # the object is undumpable.  The dumps are basically data produced
         
     | 
| 
      
 39 
     | 
    
         
            +
                # by Marshal::dump prefixed by a 32-bit length field in network
         
     | 
| 
      
 40 
     | 
    
         
            +
                # byte order.
         
     | 
| 
      
 41 
     | 
    
         
            +
                #
         
     | 
| 
      
 42 
     | 
    
         
            +
                def dump(obj, error=false)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  if obj.kind_of? DRb::DRbUndumped
         
     | 
| 
      
 44 
     | 
    
         
            +
                    obj = make_proxy(obj, error)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  end
         
     | 
| 
      
 46 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 47 
     | 
    
         
            +
                    str = Marshal::dump(obj)
         
     | 
| 
      
 48 
     | 
    
         
            +
                  rescue
         
     | 
| 
      
 49 
     | 
    
         
            +
                    str = Marshal::dump(make_proxy(obj, error))
         
     | 
| 
      
 50 
     | 
    
         
            +
                  end
         
     | 
| 
      
 51 
     | 
    
         
            +
                  return([str.size].pack("N") + str)
         
     | 
| 
      
 52 
     | 
    
         
            +
                end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                ##
         
     | 
| 
      
 55 
     | 
    
         
            +
                # Create a proxy for +obj+ that is declared to be undumpable.
         
     | 
| 
      
 56 
     | 
    
         
            +
                #
         
     | 
| 
      
 57 
     | 
    
         
            +
                def make_proxy(obj, error=false)
         
     | 
| 
      
 58 
     | 
    
         
            +
                  return(error ? DRb::DRbRemoteError.new(obj) : DRb::DRbObject.new(obj))
         
     | 
| 
      
 59 
     | 
    
         
            +
                end
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                ##
         
     | 
| 
      
 62 
     | 
    
         
            +
                # Receive data from the caller.  This basically receives packets
         
     | 
| 
      
 63 
     | 
    
         
            +
                # containing objects marshalled using Ruby's Marshal::dump prefixed
         
     | 
| 
      
 64 
     | 
    
         
            +
                # by a length.  These objects are unmarshalled and processed by the
         
     | 
| 
      
 65 
     | 
    
         
            +
                # internal object request state machine (DRbServerProtocol#receive_obj
         
     | 
| 
      
 66 
     | 
    
         
            +
                # below).  If an error of any kind occurs herein, the exception is
         
     | 
| 
      
 67 
     | 
    
         
            +
                # propagated to the caller.
         
     | 
| 
      
 68 
     | 
    
         
            +
                def receive_data(data)
         
     | 
| 
      
 69 
     | 
    
         
            +
                  @msgbuffer << data
         
     | 
| 
      
 70 
     | 
    
         
            +
                  while @msgbuffer.length > 4
         
     | 
| 
      
 71 
     | 
    
         
            +
                    length = @msgbuffer.unpack("N")[0]
         
     | 
| 
      
 72 
     | 
    
         
            +
                    if length > @load_limit
         
     | 
| 
      
 73 
     | 
    
         
            +
                      raise DRb::DRbConnError, "too large packet #{length}"
         
     | 
| 
      
 74 
     | 
    
         
            +
                    end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                    if @msgbuffer.length < length - 4
         
     | 
| 
      
 77 
     | 
    
         
            +
                      # not enough data for this length, return to event loop
         
     | 
| 
      
 78 
     | 
    
         
            +
                      # to wait for more.
         
     | 
| 
      
 79 
     | 
    
         
            +
                      break
         
     | 
| 
      
 80 
     | 
    
         
            +
                    end
         
     | 
| 
      
 81 
     | 
    
         
            +
                    length, message, @msgbuffer = @msgbuffer.unpack("Na#{length}a*")
         
     | 
| 
      
 82 
     | 
    
         
            +
                    receive_obj(obj_load(message))
         
     | 
| 
      
 83 
     | 
    
         
            +
                  end
         
     | 
| 
      
 84 
     | 
    
         
            +
                end
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                ##
         
     | 
| 
      
 87 
     | 
    
         
            +
                # Load a serialized object.
         
     | 
| 
      
 88 
     | 
    
         
            +
                def obj_load(message)
         
     | 
| 
      
 89 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 90 
     | 
    
         
            +
                    return(Marshal::load(message))
         
     | 
| 
      
 91 
     | 
    
         
            +
                  rescue NameError, ArgumentError
         
     | 
| 
      
 92 
     | 
    
         
            +
                    return(DRb::DRbUnknown.new($!, message))
         
     | 
| 
      
 93 
     | 
    
         
            +
                  end
         
     | 
| 
      
 94 
     | 
    
         
            +
                end
         
     | 
| 
      
 95 
     | 
    
         
            +
              end
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
       30 
97 
     | 
    
         
             
              ##
         
     | 
| 
       31 
98 
     | 
    
         
             
              # EventMachine server module for DRb.
         
     | 
| 
       32 
99 
     | 
    
         
             
              #
         
     | 
| 
       33 
100 
     | 
    
         
             
              module DRbServerProtocol
         
     | 
| 
      
 101 
     | 
    
         
            +
                include DRbProtocolCommon
         
     | 
| 
       34 
102 
     | 
    
         
             
                ##
         
     | 
| 
       35 
103 
     | 
    
         
             
                # The front object for this server connection.
         
     | 
| 
       36 
104 
     | 
    
         
             
                attr_accessor :front
         
     | 
| 
         @@ -80,69 +148,15 @@ module EMDRb 
     | 
|
| 
       80 
148 
     | 
    
         
             
                  @server = @argv = @argc = nil
         
     | 
| 
       81 
149 
     | 
    
         
             
                end
         
     | 
| 
       82 
150 
     | 
    
         | 
| 
       83 
     | 
    
         
            -
                ##
         
     | 
| 
       84 
     | 
    
         
            -
                # Receive data from the caller.  This basically receives packets
         
     | 
| 
       85 
     | 
    
         
            -
                # containing objects marshalled using Ruby's Marshal::dump prefixed
         
     | 
| 
       86 
     | 
    
         
            -
                # by a length.  These objects are unmarshalled and processed by the
         
     | 
| 
       87 
     | 
    
         
            -
                # internal object request state machine.  If an error of any kind
         
     | 
| 
       88 
     | 
    
         
            -
                # occurs herein, the exception is propagated to the caller.
         
     | 
| 
       89 
     | 
    
         
            -
                def receive_data(data)
         
     | 
| 
       90 
     | 
    
         
            -
                  begin
         
     | 
| 
       91 
     | 
    
         
            -
                    @msgbuffer << data
         
     | 
| 
       92 
     | 
    
         
            -
                    while @msgbuffer.length > 4
         
     | 
| 
       93 
     | 
    
         
            -
                      length = @msgbuffer.unpack("N")[0]
         
     | 
| 
       94 
     | 
    
         
            -
                      if length > @load_limit
         
     | 
| 
       95 
     | 
    
         
            -
                        raise DRb::DRbConnError, "too large packet #{length}"
         
     | 
| 
       96 
     | 
    
         
            -
                      end
         
     | 
| 
       97 
     | 
    
         
            -
                      
         
     | 
| 
       98 
     | 
    
         
            -
                      if @msgbuffer.length < length - 4
         
     | 
| 
       99 
     | 
    
         
            -
                        # not enough data for this length, return to event loop
         
     | 
| 
       100 
     | 
    
         
            -
                        # to wait for more.
         
     | 
| 
       101 
     | 
    
         
            -
                        break
         
     | 
| 
       102 
     | 
    
         
            -
                      end
         
     | 
| 
       103 
     | 
    
         
            -
                      length, message, @msgbuffer = @msgbuffer.unpack("Na#{length}a*")
         
     | 
| 
       104 
     | 
    
         
            -
                      add_obj(obj_load(message))
         
     | 
| 
       105 
     | 
    
         
            -
                    end
         
     | 
| 
       106 
     | 
    
         
            -
                  rescue Exception => e
         
     | 
| 
       107 
     | 
    
         
            -
                    send_reply(false, e)
         
     | 
| 
       108 
     | 
    
         
            -
                  end
         
     | 
| 
       109 
     | 
    
         
            -
                end
         
     | 
| 
       110 
     | 
    
         
            -
             
     | 
| 
       111 
151 
     | 
    
         
             
                private
         
     | 
| 
       112 
152 
     | 
    
         | 
| 
       113 
     | 
    
         
            -
                ##
         
     | 
| 
       114 
     | 
    
         
            -
                # This method will dump an object +obj+ using Ruby's marshalling
         
     | 
| 
       115 
     | 
    
         
            -
                # capabilities.  It will make a proxy to the object instead if
         
     | 
| 
       116 
     | 
    
         
            -
                # the object is undumpable.  The dumps are basically data produced
         
     | 
| 
       117 
     | 
    
         
            -
                # by Marshal::dump prefixed by a 32-bit length field in network
         
     | 
| 
       118 
     | 
    
         
            -
                # byte order.
         
     | 
| 
       119 
     | 
    
         
            -
                #
         
     | 
| 
       120 
     | 
    
         
            -
                def dump(obj, error=false)
         
     | 
| 
       121 
     | 
    
         
            -
                  if obj.kind_of? DRb::DRbUndumped
         
     | 
| 
       122 
     | 
    
         
            -
                    obj = make_proxy(obj, error)
         
     | 
| 
       123 
     | 
    
         
            -
                  end
         
     | 
| 
       124 
     | 
    
         
            -
                  begin
         
     | 
| 
       125 
     | 
    
         
            -
                    str = Marshal::dump(obj)
         
     | 
| 
       126 
     | 
    
         
            -
                  rescue
         
     | 
| 
       127 
     | 
    
         
            -
                    str = Marshal::dump(make_proxy(obj, error))
         
     | 
| 
       128 
     | 
    
         
            -
                  end
         
     | 
| 
       129 
     | 
    
         
            -
                  return([str.size].pack("N") + str)
         
     | 
| 
       130 
     | 
    
         
            -
                end
         
     | 
| 
       131 
     | 
    
         
            -
             
     | 
| 
       132 
     | 
    
         
            -
                ##
         
     | 
| 
       133 
     | 
    
         
            -
                # Create a proxy for +obj+ that is declared to be undumpable.
         
     | 
| 
       134 
     | 
    
         
            -
                #
         
     | 
| 
       135 
     | 
    
         
            -
                def make_proxy(obj, error=false)
         
     | 
| 
       136 
     | 
    
         
            -
                  return(error ? Drb::DRbRemoteError.new(obj) : DRb::DRbObject.new(obj))
         
     | 
| 
       137 
     | 
    
         
            -
                end
         
     | 
| 
       138 
     | 
    
         
            -
             
     | 
| 
       139 
153 
     | 
    
         
             
                ##
         
     | 
| 
       140 
154 
     | 
    
         
             
                # Send a reply to the caller.  The return value for distributed Ruby
         
     | 
| 
       141 
155 
     | 
    
         
             
                # over the wire is the success as a boolean true or false value, followed
         
     | 
| 
       142 
156 
     | 
    
         
             
                # by a dump of the data.
         
     | 
| 
       143 
157 
     | 
    
         
             
                #
         
     | 
| 
       144 
158 
     | 
    
         
             
                def send_reply(succ, result)
         
     | 
| 
       145 
     | 
    
         
            -
                  send_data(dump(succ) + dump(result, !succ)) 
     | 
| 
      
 159 
     | 
    
         
            +
                  send_data(dump(succ) + dump(result, !succ))
         
     | 
| 
       146 
160 
     | 
    
         
             
                end
         
     | 
| 
       147 
161 
     | 
    
         | 
| 
       148 
162 
     | 
    
         
             
                ##
         
     | 
| 
         @@ -229,7 +243,22 @@ module EMDRb 
     | 
|
| 
       229 
243 
     | 
    
         
             
                  return(@idconv.to_obj(ref))
         
     | 
| 
       230 
244 
     | 
    
         
             
                end
         
     | 
| 
       231 
245 
     | 
    
         | 
| 
       232 
     | 
    
         
            -
                 
     | 
| 
      
 246 
     | 
    
         
            +
                ##
         
     | 
| 
      
 247 
     | 
    
         
            +
                # This is the main state machine that processes distributed Ruby calls.
         
     | 
| 
      
 248 
     | 
    
         
            +
                # A DRb client basically sends several pieces of data in sequence, each
         
     | 
| 
      
 249 
     | 
    
         
            +
                # of which corresponds to a state of this machine.
         
     | 
| 
      
 250 
     | 
    
         
            +
                #
         
     | 
| 
      
 251 
     | 
    
         
            +
                # 1. :ref - this gives a reference to a DRb server running on the
         
     | 
| 
      
 252 
     | 
    
         
            +
                #    caller, mainly used to provide a mechanism for accessing undumpable
         
     | 
| 
      
 253 
     | 
    
         
            +
                #    objects on the caller.
         
     | 
| 
      
 254 
     | 
    
         
            +
                # 2. :msg - a symbol giving the method to be called on this server.
         
     | 
| 
      
 255 
     | 
    
         
            +
                # 3. :argc - an integer count of the number of arguments on the caller.
         
     | 
| 
      
 256 
     | 
    
         
            +
                # 4. :argv - repeats an :argc number of times, the actual arguments
         
     | 
| 
      
 257 
     | 
    
         
            +
                #    sent by the caller.
         
     | 
| 
      
 258 
     | 
    
         
            +
                # 5. :block - the block passed by the caller (generally a DRbObject
         
     | 
| 
      
 259 
     | 
    
         
            +
                #    wrapping a Proc object).
         
     | 
| 
      
 260 
     | 
    
         
            +
                #
         
     | 
| 
      
 261 
     | 
    
         
            +
                def receive_obj(obj)
         
     | 
| 
       233 
262 
     | 
    
         
             
                  @request[@state] = obj
         
     | 
| 
       234 
263 
     | 
    
         
             
                  case @state
         
     | 
| 
       235 
264 
     | 
    
         
             
                  when :ref
         
     | 
| 
         @@ -252,7 +281,7 @@ module EMDRb 
     | 
|
| 
       252 
281 
     | 
    
         
             
                      @state = :block
         
     | 
| 
       253 
282 
     | 
    
         
             
                    end
         
     | 
| 
       254 
283 
     | 
    
         
             
                  when :block
         
     | 
| 
       255 
     | 
    
         
            -
                    @request[:argv] = @argv 
     | 
| 
      
 284 
     | 
    
         
            +
                    @request[:argv] = @argv
         
     | 
| 
       256 
285 
     | 
    
         
             
                    @state = :ref
         
     | 
| 
       257 
286 
     | 
    
         
             
                    send_reply(*perform)
         
     | 
| 
       258 
287 
     | 
    
         
             
                    @request = {}
         
     | 
| 
         @@ -262,18 +291,13 @@ module EMDRb 
     | 
|
| 
       262 
291 
     | 
    
         
             
                  end
         
     | 
| 
       263 
292 
     | 
    
         
             
                end
         
     | 
| 
       264 
293 
     | 
    
         | 
| 
       265 
     | 
    
         
            -
                ##
         
     | 
| 
       266 
     | 
    
         
            -
                # Load a serialized object.
         
     | 
| 
       267 
     | 
    
         
            -
                def obj_load(message)
         
     | 
| 
       268 
     | 
    
         
            -
                  begin
         
     | 
| 
       269 
     | 
    
         
            -
                    return(Marshal::load(message))
         
     | 
| 
       270 
     | 
    
         
            -
                  rescue NameError, ArgumentError
         
     | 
| 
       271 
     | 
    
         
            -
                    return(DRb::DRbUnknown.new($!, message))
         
     | 
| 
       272 
     | 
    
         
            -
                  end
         
     | 
| 
       273 
     | 
    
         
            -
                end
         
     | 
| 
       274 
     | 
    
         
            -
             
     | 
| 
       275 
294 
     | 
    
         
             
              end
         
     | 
| 
       276 
295 
     | 
    
         | 
| 
      
 296 
     | 
    
         
            +
              ##
         
     | 
| 
      
 297 
     | 
    
         
            +
              # Class representing a drb server instance.  This subclasses DRb::DRbServer
         
     | 
| 
      
 298 
     | 
    
         
            +
              # for brevity.  DRbServer instances are normally created indirectly using
         
     | 
| 
      
 299 
     | 
    
         
            +
              # either EMDRb.start service (which emulates DRb.start_service) or via
         
     | 
| 
      
 300 
     | 
    
         
            +
              # EMDRb.start_drbserver (designed to be called from within an event loop).
         
     | 
| 
       277 
301 
     | 
    
         
             
              class DRbServer < DRb::DRbServer
         
     | 
| 
       278 
302 
     | 
    
         
             
                def initialize(uri=nil, front=nil, config_or_acl=nil)
         
     | 
| 
       279 
303 
     | 
    
         
             
                  if Hash === config_or_acl
         
     | 
| 
         @@ -290,8 +314,6 @@ module EMDRb 
     | 
|
| 
       290 
314 
     | 
    
         
             
                  @front = front
         
     | 
| 
       291 
315 
     | 
    
         
             
                  @idconv = @config[:idconv]
         
     | 
| 
       292 
316 
     | 
    
         
             
                  @safe_level = @config[:safe_level]
         
     | 
| 
       293 
     | 
    
         
            -
                  @thread = run
         
     | 
| 
       294 
     | 
    
         
            -
                  EMDRb.regist_server(self)
         
     | 
| 
       295 
317 
     | 
    
         
             
                end
         
     | 
| 
       296 
318 
     | 
    
         | 
| 
       297 
319 
     | 
    
         
             
                private
         
     | 
| 
         @@ -319,23 +341,25 @@ module EMDRb 
     | 
|
| 
       319 
341 
     | 
    
         
             
                  end
         
     | 
| 
       320 
342 
     | 
    
         
             
                end
         
     | 
| 
       321 
343 
     | 
    
         | 
| 
       322 
     | 
    
         
            -
                 
     | 
| 
       323 
     | 
    
         
            -
             
     | 
| 
       324 
     | 
    
         
            -
             
     | 
| 
       325 
     | 
    
         
            -
             
     | 
| 
       326 
     | 
    
         
            -
             
     | 
| 
       327 
     | 
    
         
            -
             
     | 
| 
       328 
     | 
    
         
            -
             
     | 
| 
       329 
     | 
    
         
            -
             
     | 
| 
       330 
     | 
    
         
            -
             
     | 
| 
       331 
     | 
    
         
            -
             
     | 
| 
       332 
     | 
    
         
            -
             
     | 
| 
       333 
     | 
    
         
            -
             
     | 
| 
       334 
     | 
    
         
            -
             
     | 
| 
       335 
     | 
    
         
            -
             
     | 
| 
       336 
     | 
    
         
            -
             
     | 
| 
       337 
     | 
    
         
            -
             
     | 
| 
       338 
     | 
    
         
            -
                     
     | 
| 
      
 344 
     | 
    
         
            +
                public
         
     | 
| 
      
 345 
     | 
    
         
            +
             
     | 
| 
      
 346 
     | 
    
         
            +
                ##
         
     | 
| 
      
 347 
     | 
    
         
            +
                # Start a DRb server from within an event loop.
         
     | 
| 
      
 348 
     | 
    
         
            +
                #
         
     | 
| 
      
 349 
     | 
    
         
            +
                def start_drb_server
         
     | 
| 
      
 350 
     | 
    
         
            +
                  @thread = Thread.current
         
     | 
| 
      
 351 
     | 
    
         
            +
                  host, port, opt = EMDRb::parse_uri(@uri)
         
     | 
| 
      
 352 
     | 
    
         
            +
                  if host.size == 0
         
     | 
| 
      
 353 
     | 
    
         
            +
                    host = self.class.host_inaddr_any
         
     | 
| 
      
 354 
     | 
    
         
            +
                  end
         
     | 
| 
      
 355 
     | 
    
         
            +
                  EventMachine::start_server(host, port, DRbServerProtocol) do |conn|
         
     | 
| 
      
 356 
     | 
    
         
            +
                    Thread.current['DRb'] = { 'client' => conn, 'server' => self }
         
     | 
| 
      
 357 
     | 
    
         
            +
                    conn.front = @front
         
     | 
| 
      
 358 
     | 
    
         
            +
                    conn.load_limit = @config[:load_limit]
         
     | 
| 
      
 359 
     | 
    
         
            +
                    conn.argc_limit = @config[:argc_limit]
         
     | 
| 
      
 360 
     | 
    
         
            +
                    conn.idconv = @config[:idconv]
         
     | 
| 
      
 361 
     | 
    
         
            +
                    conn.server = self
         
     | 
| 
      
 362 
     | 
    
         
            +
                    conn.safe_level = self.safe_level
         
     | 
| 
       339 
363 
     | 
    
         
             
                  end
         
     | 
| 
       340 
364 
     | 
    
         
             
                end
         
     | 
| 
       341 
365 
     | 
    
         | 
| 
         @@ -357,9 +381,38 @@ module EMDRb 
     | 
|
| 
       357 
381 
     | 
    
         
             
              module_function :parse_uri
         
     | 
| 
       358 
382 
     | 
    
         | 
| 
       359 
383 
     | 
    
         
             
              @primary_server = nil
         
     | 
| 
      
 384 
     | 
    
         
            +
              @eventloop = nil
         
     | 
| 
       360 
385 
     | 
    
         | 
| 
      
 386 
     | 
    
         
            +
              ##
         
     | 
| 
      
 387 
     | 
    
         
            +
              # This is the 'bare bones' start_service which can be used to
         
     | 
| 
      
 388 
     | 
    
         
            +
              # start a DRb service from within an existing event loop.
         
     | 
| 
      
 389 
     | 
    
         
            +
              def start_drbserver(uri=nil, front=nil, config=nil)
         
     | 
| 
      
 390 
     | 
    
         
            +
                serv = DRbServer.new(uri, front, config)
         
     | 
| 
      
 391 
     | 
    
         
            +
                serv.start_drb_server
         
     | 
| 
      
 392 
     | 
    
         
            +
                return(serv)
         
     | 
| 
      
 393 
     | 
    
         
            +
              end
         
     | 
| 
      
 394 
     | 
    
         
            +
              module_function :start_drbserver
         
     | 
| 
      
 395 
     | 
    
         
            +
             
     | 
| 
      
 396 
     | 
    
         
            +
              ##
         
     | 
| 
      
 397 
     | 
    
         
            +
              # This start_service emulates DRb#start_service.
         
     | 
| 
      
 398 
     | 
    
         
            +
              #
         
     | 
| 
       361 
399 
     | 
    
         
             
              def start_service(uri=nil, front=nil, config=nil)
         
     | 
| 
       362 
     | 
    
         
            -
                 
     | 
| 
      
 400 
     | 
    
         
            +
                unless EventMachine::reactor_running?
         
     | 
| 
      
 401 
     | 
    
         
            +
                  @eventloop = Thread.new do
         
     | 
| 
      
 402 
     | 
    
         
            +
                    EventMachine::run do
         
     | 
| 
      
 403 
     | 
    
         
            +
                      # Start an empty event loop.  The DRb server(s) will be started
         
     | 
| 
      
 404 
     | 
    
         
            +
                      # by EM#next_tick calls.
         
     | 
| 
      
 405 
     | 
    
         
            +
                    end
         
     | 
| 
      
 406 
     | 
    
         
            +
                  end
         
     | 
| 
      
 407 
     | 
    
         
            +
                end
         
     | 
| 
      
 408 
     | 
    
         
            +
                queue = Queue.new
         
     | 
| 
      
 409 
     | 
    
         
            +
                EventMachine::next_tick do
         
     | 
| 
      
 410 
     | 
    
         
            +
                  queue << self.start_drbserver(uri, front, config)
         
     | 
| 
      
 411 
     | 
    
         
            +
                end
         
     | 
| 
      
 412 
     | 
    
         
            +
                serv = queue.shift
         
     | 
| 
      
 413 
     | 
    
         
            +
                @primary_server = serv
         
     | 
| 
      
 414 
     | 
    
         
            +
                EMDRb.regist_server(serv)
         
     | 
| 
      
 415 
     | 
    
         
            +
                return(serv)
         
     | 
| 
       363 
416 
     | 
    
         
             
              end
         
     | 
| 
       364 
417 
     | 
    
         
             
              module_function :start_service
         
     | 
| 
       365 
418 
     | 
    
         | 
| 
         @@ -403,4 +456,93 @@ module EMDRb 
     | 
|
| 
       403 
456 
     | 
    
         
             
              end
         
     | 
| 
       404 
457 
     | 
    
         
             
              module_function :thread
         
     | 
| 
       405 
458 
     | 
    
         | 
| 
      
 459 
     | 
    
         
            +
             
     | 
| 
      
 460 
     | 
    
         
            +
              ##
         
     | 
| 
      
 461 
     | 
    
         
            +
              # Client protocol module 
         
     | 
| 
      
 462 
     | 
    
         
            +
              module DRbClientProtocol
         
     | 
| 
      
 463 
     | 
    
         
            +
                include DRbProtocolCommon
         
     | 
| 
      
 464 
     | 
    
         
            +
             
     | 
| 
      
 465 
     | 
    
         
            +
                attr_accessor :ref
         
     | 
| 
      
 466 
     | 
    
         
            +
                attr_accessor :msg_id
         
     | 
| 
      
 467 
     | 
    
         
            +
                attr_accessor :args
         
     | 
| 
      
 468 
     | 
    
         
            +
                attr_accessor :block
         
     | 
| 
      
 469 
     | 
    
         
            +
                attr_accessor :df
         
     | 
| 
      
 470 
     | 
    
         
            +
             
     | 
| 
      
 471 
     | 
    
         
            +
                def post_init
         
     | 
| 
      
 472 
     | 
    
         
            +
                  @msgbuffer = ""
         
     | 
| 
      
 473 
     | 
    
         
            +
                  @idconv = DRb::DRbIdConv.new
         
     | 
| 
      
 474 
     | 
    
         
            +
                  @load_limit = DEFAULT_LOAD_LIMIT
         
     | 
| 
      
 475 
     | 
    
         
            +
                end
         
     | 
| 
      
 476 
     | 
    
         
            +
             
     | 
| 
      
 477 
     | 
    
         
            +
                def connection_completed
         
     | 
| 
      
 478 
     | 
    
         
            +
                  @connected = true
         
     | 
| 
      
 479 
     | 
    
         
            +
                  send_request(@ref, @msg_id, @args, @block)
         
     | 
| 
      
 480 
     | 
    
         
            +
                  @state = :succ
         
     | 
| 
      
 481 
     | 
    
         
            +
                  @succ = nil
         
     | 
| 
      
 482 
     | 
    
         
            +
                  @result = nil
         
     | 
| 
      
 483 
     | 
    
         
            +
                end
         
     | 
| 
      
 484 
     | 
    
         
            +
             
     | 
| 
      
 485 
     | 
    
         
            +
                def send_request(ref, msgid, arg, block)
         
     | 
| 
      
 486 
     | 
    
         
            +
                  ary = []
         
     | 
| 
      
 487 
     | 
    
         
            +
                  ary.push(dump(ref.__drbref))
         
     | 
| 
      
 488 
     | 
    
         
            +
                  ary.push(dump(msg_id.id2name))
         
     | 
| 
      
 489 
     | 
    
         
            +
                  ary.push(dump(arg.length))
         
     | 
| 
      
 490 
     | 
    
         
            +
                  arg.each do |e|
         
     | 
| 
      
 491 
     | 
    
         
            +
            	ary.push(dump(e))
         
     | 
| 
      
 492 
     | 
    
         
            +
                  end
         
     | 
| 
      
 493 
     | 
    
         
            +
                  ary.push(dump(block))
         
     | 
| 
      
 494 
     | 
    
         
            +
                  send_data(ary.join(''))
         
     | 
| 
      
 495 
     | 
    
         
            +
                end
         
     | 
| 
      
 496 
     | 
    
         
            +
             
     | 
| 
      
 497 
     | 
    
         
            +
                def receive_obj(obj)
         
     | 
| 
      
 498 
     | 
    
         
            +
                  if @state == :succ
         
     | 
| 
      
 499 
     | 
    
         
            +
                    @succ = obj
         
     | 
| 
      
 500 
     | 
    
         
            +
                    @state = :result
         
     | 
| 
      
 501 
     | 
    
         
            +
                  else
         
     | 
| 
      
 502 
     | 
    
         
            +
                    @result = obj
         
     | 
| 
      
 503 
     | 
    
         
            +
                    @state = :succ
         
     | 
| 
      
 504 
     | 
    
         
            +
                    @df.set_deferred_status(:succeeded, [@succ, @result])
         
     | 
| 
      
 505 
     | 
    
         
            +
                    # close the connection after the call succeeds.
         
     | 
| 
      
 506 
     | 
    
         
            +
                    close_connection
         
     | 
| 
      
 507 
     | 
    
         
            +
                  end
         
     | 
| 
      
 508 
     | 
    
         
            +
                end
         
     | 
| 
      
 509 
     | 
    
         
            +
              end
         
     | 
| 
      
 510 
     | 
    
         
            +
             
     | 
| 
      
 511 
     | 
    
         
            +
              ##
         
     | 
| 
      
 512 
     | 
    
         
            +
              # Object wrapping a reference to a remote drb object.
         
     | 
| 
      
 513 
     | 
    
         
            +
              #
         
     | 
| 
      
 514 
     | 
    
         
            +
              # Method calls on this object are relayed to the remote object
         
     | 
| 
      
 515 
     | 
    
         
            +
              # that this object is a stub for.
         
     | 
| 
      
 516 
     | 
    
         
            +
              class DRbObject < DRb::DRbObject
         
     | 
| 
      
 517 
     | 
    
         
            +
                def initialize(obj, uri=nil)
         
     | 
| 
      
 518 
     | 
    
         
            +
                  @uri = nil
         
     | 
| 
      
 519 
     | 
    
         
            +
                  @ref = nil
         
     | 
| 
      
 520 
     | 
    
         
            +
                  if obj.nil?
         
     | 
| 
      
 521 
     | 
    
         
            +
            	return if uri.nil?
         
     | 
| 
      
 522 
     | 
    
         
            +
                    @uri = uri
         
     | 
| 
      
 523 
     | 
    
         
            +
                    ref = nil
         
     | 
| 
      
 524 
     | 
    
         
            +
                    @host, @port, @opt = EMDRb::parse_uri(@uri)
         
     | 
| 
      
 525 
     | 
    
         
            +
                  else
         
     | 
| 
      
 526 
     | 
    
         
            +
                    @ref = obj
         
     | 
| 
      
 527 
     | 
    
         
            +
                  end
         
     | 
| 
      
 528 
     | 
    
         
            +
                end
         
     | 
| 
      
 529 
     | 
    
         
            +
             
     | 
| 
      
 530 
     | 
    
         
            +
                ##
         
     | 
| 
      
 531 
     | 
    
         
            +
                # Perform an asynchronous call to the remote object.  This can only
         
     | 
| 
      
 532 
     | 
    
         
            +
                # be used from within an event loop.  It returns a deferrable to which
         
     | 
| 
      
 533 
     | 
    
         
            +
                # callbacks can be attached.
         
     | 
| 
      
 534 
     | 
    
         
            +
                def send_async(msg_id, *a, &b)
         
     | 
| 
      
 535 
     | 
    
         
            +
                  df = EventMachine::DefaultDeferrable.new
         
     | 
| 
      
 536 
     | 
    
         
            +
                  EventMachine.connect(@host, @port, DRbClientProtocol) do |c|
         
     | 
| 
      
 537 
     | 
    
         
            +
                    c.ref = self
         
     | 
| 
      
 538 
     | 
    
         
            +
                    c.msg_id = msg_id
         
     | 
| 
      
 539 
     | 
    
         
            +
                    c.args = a
         
     | 
| 
      
 540 
     | 
    
         
            +
                    c.block = b
         
     | 
| 
      
 541 
     | 
    
         
            +
                    c.df = df
         
     | 
| 
      
 542 
     | 
    
         
            +
                  end
         
     | 
| 
      
 543 
     | 
    
         
            +
                  return(df)
         
     | 
| 
      
 544 
     | 
    
         
            +
                end
         
     | 
| 
      
 545 
     | 
    
         
            +
             
     | 
| 
      
 546 
     | 
    
         
            +
              end
         
     | 
| 
      
 547 
     | 
    
         
            +
             
     | 
| 
       406 
548 
     | 
    
         
             
            end
         
     | 
    
        data/lib/emdrb/version.rb
    CHANGED
    
    | 
         @@ -4,7 +4,7 @@ 
     | 
|
| 
       4 
4 
     | 
    
         
             
            # Homepage:: http://emdrb.rubyforge.org/
         
     | 
| 
       5 
5 
     | 
    
         
             
            # License:: GNU Lesser General Public License / Ruby License
         
     | 
| 
       6 
6 
     | 
    
         
             
            #
         
     | 
| 
       7 
     | 
    
         
            -
            # $Id: version.rb  
     | 
| 
      
 7 
     | 
    
         
            +
            # $Id: version.rb 26 2009-01-22 04:48:43Z dido $
         
     | 
| 
       8 
8 
     | 
    
         
             
            #
         
     | 
| 
       9 
9 
     | 
    
         
             
            #----------------------------------------------------------------------------
         
     | 
| 
       10 
10 
     | 
    
         
             
            #
         
     | 
| 
         @@ -26,7 +26,7 @@ module EMDRb 
     | 
|
| 
       26 
26 
     | 
    
         | 
| 
       27 
27 
     | 
    
         
             
                MAJOR = 0
         
     | 
| 
       28 
28 
     | 
    
         
             
                MINOR = 1
         
     | 
| 
       29 
     | 
    
         
            -
                TINY =  
     | 
| 
      
 29 
     | 
    
         
            +
                TINY = 2
         
     | 
| 
       30 
30 
     | 
    
         | 
| 
       31 
31 
     | 
    
         
             
                # The version of EMDRb in use.
         
     | 
| 
       32 
32 
     | 
    
         
             
                STRING = [ MAJOR, MINOR, TINY ].join(".")
         
     | 
    
        data/test/test_emdrb.rb
    CHANGED
    
    | 
         @@ -4,7 +4,7 @@ 
     | 
|
| 
       4 
4 
     | 
    
         
             
            # Homepage:: http://emdrb.rubyforge.org/
         
     | 
| 
       5 
5 
     | 
    
         
             
            # License:: GNU General Public License / Ruby License
         
     | 
| 
       6 
6 
     | 
    
         
             
            #
         
     | 
| 
       7 
     | 
    
         
            -
            # $Id: test_emdrb.rb  
     | 
| 
      
 7 
     | 
    
         
            +
            # $Id: test_emdrb.rb 27 2009-01-22 05:11:56Z dido $
         
     | 
| 
       8 
8 
     | 
    
         
             
            #
         
     | 
| 
       9 
9 
     | 
    
         
             
            #----------------------------------------------------------------------------
         
     | 
| 
       10 
10 
     | 
    
         
             
            #
         
     | 
| 
         @@ -46,8 +46,15 @@ class TestServer 
     | 
|
| 
       46 
46 
     | 
    
         
             
            end
         
     | 
| 
       47 
47 
     | 
    
         | 
| 
       48 
48 
     | 
    
         
             
            class EMDRbTest < Test::Unit::TestCase
         
     | 
| 
       49 
     | 
    
         
            -
              def  
     | 
| 
      
 49 
     | 
    
         
            +
              def setup
         
     | 
| 
       50 
50 
     | 
    
         
             
                EMDRb.start_service("druby://:12345", TestServer.new)
         
     | 
| 
      
 51 
     | 
    
         
            +
              end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
              def teardown
         
     | 
| 
      
 54 
     | 
    
         
            +
                EMDRb.thread.kill
         
     | 
| 
      
 55 
     | 
    
         
            +
              end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
              def test_server
         
     | 
| 
       51 
58 
     | 
    
         
             
                o = DRbObject.new_with_uri("druby://localhost:12345")
         
     | 
| 
       52 
59 
     | 
    
         
             
                DRb.start_service
         
     | 
| 
       53 
60 
     | 
    
         
             
                assert_equal(1, o.identity(1))
         
     | 
| 
         @@ -61,4 +68,29 @@ class EMDRbTest < Test::Unit::TestCase 
     | 
|
| 
       61 
68 
     | 
    
         
             
                assert_equal(5040, val)
         
     | 
| 
       62 
69 
     | 
    
         
             
              end
         
     | 
| 
       63 
70 
     | 
    
         | 
| 
      
 71 
     | 
    
         
            +
              def test_client
         
     | 
| 
      
 72 
     | 
    
         
            +
                o = EMDRb::DRbObject.new(nil, "druby://localhost:12345")
         
     | 
| 
      
 73 
     | 
    
         
            +
                q = Queue.new
         
     | 
| 
      
 74 
     | 
    
         
            +
                EventMachine::next_tick do
         
     | 
| 
      
 75 
     | 
    
         
            +
                  o.send_async(:identity, 1).callback do |data|
         
     | 
| 
      
 76 
     | 
    
         
            +
                    assert(data[0])
         
     | 
| 
      
 77 
     | 
    
         
            +
                    assert_equal(1, data[1])
         
     | 
| 
      
 78 
     | 
    
         
            +
                    q << data
         
     | 
| 
      
 79 
     | 
    
         
            +
                  end
         
     | 
| 
      
 80 
     | 
    
         
            +
                end
         
     | 
| 
      
 81 
     | 
    
         
            +
                q.shift
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
            #    EventMachine::next_tick do
         
     | 
| 
      
 84 
     | 
    
         
            +
            #      val = 1
         
     | 
| 
      
 85 
     | 
    
         
            +
            #      df = o.send_async(:blockyield, 1,2,3,4,5,6,7) { |x| val *= x; val }
         
     | 
| 
      
 86 
     | 
    
         
            +
            #      df.callback do |data|
         
     | 
| 
      
 87 
     | 
    
         
            +
            #        assert(data[0])
         
     | 
| 
      
 88 
     | 
    
         
            +
            #        assert_equal(5040, data[1])
         
     | 
| 
      
 89 
     | 
    
         
            +
            #        q << data
         
     | 
| 
      
 90 
     | 
    
         
            +
            #      end
         
     | 
| 
      
 91 
     | 
    
         
            +
            #    end
         
     | 
| 
      
 92 
     | 
    
         
            +
            #    q.shift
         
     | 
| 
      
 93 
     | 
    
         
            +
             
     | 
| 
      
 94 
     | 
    
         
            +
              end
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
       64 
96 
     | 
    
         
             
            end
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification 
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: emdrb
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version 
         
     | 
| 
       4 
     | 
    
         
            -
              version: 0.1. 
     | 
| 
      
 4 
     | 
    
         
            +
              version: 0.1.2
         
     | 
| 
       5 
5 
     | 
    
         
             
            platform: ruby
         
     | 
| 
       6 
6 
     | 
    
         
             
            authors: 
         
     | 
| 
       7 
7 
     | 
    
         
             
            - dido@imperium.ph
         
     | 
| 
         @@ -9,7 +9,7 @@ autorequire: 
     | 
|
| 
       9 
9 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       10 
10 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       11 
11 
     | 
    
         | 
| 
       12 
     | 
    
         
            -
            date:  
     | 
| 
      
 12 
     | 
    
         
            +
            date: 2009-01-22 00:00:00 +08:00
         
     | 
| 
       13 
13 
     | 
    
         
             
            default_executable: 
         
     | 
| 
       14 
14 
     | 
    
         
             
            dependencies: []
         
     | 
| 
       15 
15 
     | 
    
         |