class Pione::Front::BasicFront

This is base class for all PIONE front classes. PIONE fronts exist in each command and behave as remote control interface.

Attributes

uri[R]

Public Class Methods

new(cmd, port) click to toggle source

Creates a front server as druby’s service.

# File lib/pione/front/basic-front.rb, line 11
def initialize(cmd, port)
  @cmd = cmd
  @uri = URI.parse(start_service(port, {})) # port is number or range
  @attr = {}
  @child = {}
  @child_lock = Mutex.new
  @child_watchers = ThreadGroup.new
end

Public Instance Methods

[](name) click to toggle source
# File lib/pione/front/basic-front.rb, line 25
def [](name)
  @attr[name]
end
[]=(name, val) click to toggle source
# File lib/pione/front/basic-front.rb, line 29
def []=(name, val)
  @attr[name] = val
end
child_front_uri(pid) click to toggle source

Return a front URI of the child PID.

@return [String]

URI of the child PID
# File lib/pione/front/basic-front.rb, line 91
def child_front_uri(pid)
  @child[pid]
end
child_pids() click to toggle source

Return list of child process’s PIDs.

@return [Array]

list of child command's PIDs.
# File lib/pione/front/basic-front.rb, line 83
def child_pids
  @child.keys
end
pid() click to toggle source

Return PID of the process.

# File lib/pione/front/basic-front.rb, line 21
def pid
  Process.pid
end
register_child(pid, front_uri) click to toggle source

Register the process as a child of this process. It is unregistered when the child is terminated.

@param pid [String]

child process's PID

@param front_uri [String]

child process's front URI

@return [void]

# File lib/pione/front/basic-front.rb, line 41
def register_child(pid, front_uri)
  unless @cmd.current_phase == :termination
    # register child's PID
    @child_lock.synchronize {@child[pid] = front_uri}

    # unregister automatically when the child is terminated
    thread = Thread.new do
      Util.ignore_exception(Errno::ECHILD) do
        Process.waitpid(pid)
        unregister_child(pid)
      end
    end
    thread[:pid] = pid
    @child_watchers.add(thread)

    return nil
  else
    raise ChildRegistrationError.new
  end
end
system_logger() click to toggle source
# File lib/pione/front/basic-front.rb, line 95
def system_logger
  Log::SystemLog.logger
end
terminate() click to toggle source

Terminate the front server. This method assumes to be not called from other processes. Note that front servers have no responsibility of killing child processes.

# File lib/pione/front/basic-front.rb, line 102
def terminate
  DRb.stop_service
end
terminate_command() click to toggle source

Terminate the command. This is a nonblocking method because callee process cannot tell its termination to caller, so it returns true immediately.

# File lib/pione/front/basic-front.rb, line 109
def terminate_command
  Thread.new {@cmd.terminate}
  return true
end
unregister_child(pid) click to toggle source

Unregister the child process.

@param pid [String]

child's PID to be removed
# File lib/pione/front/basic-front.rb, line 66
def unregister_child(pid)
  # unregister the pid
  @child_lock.synchronize {@child.delete(pid)}

  # kill the watcher thread
  @child_watchers.list.each do |thread|
    if thread[:pid] == pid
      thread.kill
      break
    end
  end
end

Private Instance Methods

build_uri(port) click to toggle source

Build front server URI. Note that the address is configured by ‘Global.communication_address`.

# File lib/pione/front/basic-front.rb, line 144
def build_uri(port)
  "druby://%s:%s" % [Global.communication_address, port]
end
non_blocking(&b) click to toggle source

This provides non blocking API.

# File lib/pione/front/basic-front.rb, line 137
def non_blocking(&b)
  Thread.new {b.call}
  return nil
end
start_service(port, config) click to toggle source

Start DRb service and return the URI string.

# File lib/pione/front/basic-front.rb, line 117
def start_service(port, config)
  if port.kind_of?(Range)
    enum = port.each
    begin
      DRb.start_service(build_uri(enum.next), self, config)
    rescue StopIteration => e
      raise
    rescue
      retry
    end
  else
    DRb.start_service(build_uri(port), self, config)
  end

  return DRb.uri
rescue => e
  raise FrontServerError.new(self, e)
end