Class: Cosmos::JsonDRbObject

Inherits:
Object
  • Object
show all
Defined in:
lib/cosmos/io/json_drb_object.rb

Overview

Used to forward all method calls to the remote server object. Before using this class ensure the remote service has been started in the server class:

json = JsonDrb.new
json.start_service('127.0.0.1', 7777, self)

Now the JsonDRbObject can be used to call server methods directly:

server = JsonDRbObject('127.0.0.1', 7777)
server.cmd(*args)

Instance Method Summary collapse

Constructor Details

#initialize(hostname, port, connect_timeout = 1.0) ⇒ JsonDRbObject

Returns a new instance of JsonDRbObject.

Parameters:

  • hostname (String)

    The name of the machine which has started the JSON service

  • port (Integer)

    The port number of the JSON service



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/cosmos/io/json_drb_object.rb', line 36

def initialize(hostname, port, connect_timeout = 1.0)
  hostname = '127.0.0.1' if (hostname.to_s.upcase == 'LOCALHOST')
  begin
    @addr = Socket.pack_sockaddr_in(port, hostname)
  rescue => error
    if error.message =~ /getaddrinfo/
      raise "Invalid hostname: #{hostname}"
    else
      raise error
    end
  end
  @hostname = hostname
  @port = port
  @mutex = Mutex.new
  @socket = nil
  @pipe_reader, @pipe_writer = IO.pipe
  @id = 0
  @request_in_progress = false
  @connect_timeout = connect_timeout
  @connect_timeout = @connect_timeout.to_f if @connect_timeout
  @shutdown = false
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *method_params) ⇒ Object

Forwards all method calls to the remote service.

Parameters:

  • method_name (Symbol)

    Name of the method to call

  • method_params (Array)

    Array of parameters to pass to the method

Returns:

  • The result of the method call. If the method raises an exception the same exception is also raised. If something goes wrong with the protocol a DRb::DRbConnError exception is raised.



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/cosmos/io/json_drb_object.rb', line 82

def method_missing(method_name, *method_params)
  @mutex.synchronize do
    # This flag and loop are used to automatically reconnect and retry if something goes
    # wrong on the first attempt writing to the socket.   Sockets can become disconnected
    # between function calls, but as long as the remote server is back up and running the
    # call should succeed even when it discovers a broken socket on the first attempt.
    first_try = true
    loop do
      raise DRb::DRbConnError, "Shutdown" if @shutdown
      connect() if !@socket or @socket.closed? or @request_in_progress

      response = make_request(method_name, method_params, first_try)
      unless response
        disconnect()
        @socket = nil
        was_first_try = first_try
        first_try = false
        next if was_first_try
      end
      return handle_response(response)
    end # loop
  end # @mutex.synchronize
end

Instance Method Details

#disconnectObject

Disconnects from the JSON server



60
61
62
63
64
65
66
67
# File 'lib/cosmos/io/json_drb_object.rb', line 60

def disconnect
  Cosmos.close_socket(@socket)
  @pipe_writer.write('.')
  # Cannot set @socket to nil here because this method can be called by
  # other threads and @socket being nil would cause unexpected errors in method_missing
  # Also don't want to take the mutex so that we can interrupt method_missing if necessary
  # Only method_missing can set @socket to nil
end

#shutdownObject

Permanently disconnects from the JSON server



70
71
72
73
# File 'lib/cosmos/io/json_drb_object.rb', line 70

def shutdown
  @shutdown = true
  disconnect()
end