class MsgPackRPCServer

This class is a thin layer over MessagePack::RPC::Server, which implements privilege dropping and daemonizing.

Signal handlers call a close method, which the handler class must implement, and in which e.g. database connections are closed.

Server example:

 require 'msgpack_rpc_server'

 msgpack_config = {:uid => 'nobody',
                   :gid => 'nobody',
                   :listen_ip => '127.0.0.1',
                   :port => 12345,
                   :dir => '.',
                   :app_name => 'test_server',
                   :ontop => false,
                   :backtrace => true,
                   :dir_mode => :script,
                   :log_output => true }

class Handler
    def ping(arg); "pong received #{arg}"; end
    def close; nil; end
end

MsgPackRPCServer.new(msgpack_config, Handler.new).run

Client example:

require 'msgpack/rpc'

c = MessagePack::RPC::Client.new('127.0.0.1', 12345)
puts c.call(:ping, "hello")

MessagePack documentation: msgpack.org/

Daemons documentation: daemons.rubyforge.org/

Public Class Methods

new(config, handler) click to toggle source

Returns a new instance. The first parameter is a hash containing configuration parameters. Refer to the example and the Daemons library documentation for the format and meanings of configuration parameters. The other parameter is an instance of the handler class.

# File lib/msgpack_rpc_server.rb, line 51
def initialize(config, handler)
        @config = config
        @handler = handler
end

Public Instance Methods

run() click to toggle source

Starts the server after daemonizing and privilege dropping. Sets signal handlers for INT and TERM.

# File lib/msgpack_rpc_server.rb, line 85
def run
        daemonize
        drop_privileges

        Signal.trap('INT') { log "received INT signal; exiting."; close; exit }
        Signal.trap('TERM') { log "received TERM signal; exiting."; close; exit }

        svr = MessagePack::RPC::Server.new
        svr.listen @config[:listen_ip], @config[:port], @handler
        log "starting."
        svr.run
end

Private Instance Methods

close() click to toggle source

Calls the close method of the handler class.

# File lib/msgpack_rpc_server.rb, line 77
def close
        @handler.close
        log "handler closed."
end
daemonize() click to toggle source

Daemonizes this process according to the configuration parameters given to new.

# File lib/msgpack_rpc_server.rb, line 60
def daemonize
        Daemons.daemonize({:ontop => @config[:ontop], :backtrace => @config[:backtrace], :dir => @config[:dir], 
                           :app_name => @config[:app_name], :dir_mode => @config[:dir_mode], 
                           :log_output => @config[:log_output]})
        log "daemonized."
end
drop_privileges() click to toggle source

Drops privileges according to the configuration parameters given to new.

# File lib/msgpack_rpc_server.rb, line 68
def drop_privileges
        gid = Etc::getgrnam(@config[:gid])[:gid]
        uid = Etc::getpwnam(@config[:uid])[:uid]
        Process::GID.change_privilege(gid)
        Process::UID.change_privilege(uid)
        log "privileges dropped."
end
log(msg) click to toggle source

Logger library seemed to be incompatible with Daemons library, which is why logging is implemented in this very simple way for now.

# File lib/msgpack_rpc_server.rb, line 57
def log(msg); puts "#{Time.new.to_s}: #{msg}"; end