lib/vedeu/distributed/server.rb
# frozen_string_literal: true
module Vedeu
# Provides a mechanism to control a running client application via
# DRb.
#
module Distributed
# A class for the server side of the DRb server/client
# relationship.
#
# @api private
#
class Server
$SAFE = 1 # disable `eval` and related calls on strings passed
include Singleton
class << self
# @param (see #input)
# @see #input
def input(data, type = :key)
instance.input(data, type)
end
# @return [void]
# @see #output
def output
instance.output
end
# @return [void]
# @see #restart
def restart
instance.restart
end
alias drb_restart restart
# @return [void]
# @see #shutdown
def shutdown
instance.shutdown
end
# @return [void]
# @see #start
def start
instance.start
end
alias drb_start start
# @return [Symbol]
# @see #status
def status
instance.status
end
alias drb_status status
# @return [void]
# @see #stop
def stop
instance.stop
end
alias drb_stop stop
end # Eigenclass
# @param data [String|Symbol] The input to send to Vedeu.
# @param type [Symbol] Either :command or :keypress. Will
# trigger the respective capture mode within
# {Vedeu::Input::Input}, or if not given, will treat the data
# as a keypress.
# @return [void]
def input(data, type = :keypress)
Vedeu.trigger(:_drb_input_, data, type)
end
alias read input
# @return [void]
def output
Vedeu.trigger(:_drb_retrieve_output_)
end
alias write output
# @return [Fixnum] The PID of the currently running application.
def pid
Process.pid
end
# Restart the DRb server.
#
# @example
# Vedeu.drb_restart
#
# @return [void]
def restart
log('Attempting to restart')
return not_enabled unless Vedeu.config.drb?
if drb_running?
log('Restarting')
stop
else
log('Not running')
end
start
end
# When called will stop the DRb server and attempt to terminate
# the client application.
#
# @note
# :_exit_ never gets triggered as when the DRb server goes
# away, no further methods will be called.
#
# @return [void]
def shutdown
return not_enabled unless Vedeu.config.drb?
stop if drb_running?
Vedeu.trigger(:_exit_)
Vedeu::Terminal.restore_screen
end
# Start the DRb server.
#
# @example
# Vedeu.drb_start
#
# @return [Vedeu::Distributed::Server]
def start
log('Attempting to start')
return not_enabled unless Vedeu.config.drb?
if drb_running?
log('Already started')
else
log('Starting')
DRb.start_service(uri, self)
# DRb.thread.join # not convinced this is needed here
end
end
# Fetch the status of the DRb server.
#
# @example
# Vedeu.drb_status
#
# @return [Symbol]
def status
log('Fetching status')
return not_enabled unless Vedeu.config.drb?
if drb_running?
log('Running')
:running
else
log('Stopped')
:stopped
end
end
# Stop the DRb server.
#
# @example
# Vedeu.drb_stop
#
# @return [void]
def stop
log('Attempting to stop')
return not_enabled unless Vedeu.config.drb?
if drb_running?
log('Stopping')
DRb.stop_service
DRb.thread.join
else
log('Already stopped')
end
rescue NoMethodError # raised when #join is called on NilClass.
Vedeu.log(type: :drb,
message: 'Attempted to #join on DRb.thread.')
end
protected
# @!attribute [r] configuration
# @return [Vedeu::Configuration]
attr_reader :configuration
private
# @return [|NilClass]
def drb_running?
DRb.thread
end
# @return [void]
def log(message)
Vedeu.log(type: :drb, message: "#{message}: '#{uri}'")
end
# @return [Symbol]
def not_enabled
log('Not enabled')
:drb_not_enabled
end
# @return [String]
def uri
Vedeu::Distributed::Uri.new(Vedeu.config.drb_host,
Vedeu.config.drb_port).to_s
end
end # Server
end # Distributed
# @api public
# @!method drb_restart
# @see Vedeu::Distributed::Server#restart
# @api public
# @!method drb_start
# @see Vedeu::Distributed::Server#start
# @api public
# @!method drb_status
# @see Vedeu::Distributed::Server#status
# @api public
# @!method drb_stop
# @see Vedeu::Distributed::Server#stop
def_delegators Vedeu::Distributed::Server,
:drb_restart,
:drb_start,
:drb_status,
:drb_stop
end # Vedeu