lib/hara/app.rb in hara-0.1.0 vs lib/hara/app.rb in hara-0.2.0

- old
+ new

@@ -1,135 +1,108 @@ -require 'celluloid/io' +require "hara/version" +require 'celluloid' require 'json' module Hara + class << self + def env + @_env ||= (ENV['APP_ENV'] || :development).to_sym + end + + def env= env + @_env = env + end + + def decode_msg msg + msg = JSON.parse(msg) + msg.values_at 'action', 'args' + end + + def encode_msg action, *args + {action: action, args: args}.to_json + end + end + class App - include Celluloid::IO + include Celluloid include Celluloid::Logger - attr_reader :socket + attr_reader :socket, :handshake - alias halt terminate - finalizer :app_finalizer Actions = {} class << self def inherited klass - ::Hara.const_set :Application, klass + ::Hara.const_set :Application, klass end def define_action action, &block - action = action.to_s - warn "Action #{action} duplication defined" if Actions.has_key? action - Hara::Application.send :define_method, action, &block - method = Hara::Application.send :instance_method, action - Hara::Application.send :remove_method, action - Actions[action] = method + action = action.to_s + warn "Action #{action} duplication defined" if Actions.has_key? action + Hara::Application.send :define_method, action, &block + method = Hara::Application.send :instance_method, action + Hara::Application.send :remove_method, action + Actions[action] = method end end - - def init + def after_connect end - #return true or false - def authentication - true - end - - def authentication_failed - halt - end - - #after_authentication only called when authentication succeeded - def after_authentication - end - def before_action action, args end def after_action action, args end - def after_process - end - def action_missing action, args - info " #{socket.remote_ip} request action: #{action} args: #{args.inspect}, action not defined" + info "#{headers['host']} request action: #{action} args: #{args.inspect}, action not defined" + raise NoMethodError, "undefined action '#{action}' for #{self}:#{self.class}" end - def command - @command || {} + def headers + handshake.headers_downcased end def on_close end - private - def initialize socket + #below are internal functions(should not been overriding) + + def initialize handshake, socket + @handshake = handshake @socket = socket - async.setup + async.hara_setup end - def setup - init - info "#{socket.remote_ip} coming" - unless authentication - authentication_failed - else - after_authentication - async.run - end + def hara_setup + info "#{headers['host']} coming" + after_connect end - def run - while msg = @socket.read - process msg - if @closed - terminate - return - end - end - rescue Reel::SocketError, EOFError #client disconnect - info "#{socket.remote_ip} disconnect" - begin - @closed = true unless @closed - on_close - ensure - terminate - end - end - - def process message - @command = JSON.parse(message) - action = @command["action"] - args = @command["args"] - info "#{socket.remote_ip} request action: #{action} args: #{args.inspect}" + def process_msg message + action, args = Hara.decode_msg(message) + info "#{headers['host']} request action: #{action} args: #{args.inspect}" before_action action, *args call_action action, *args after_action action, *args - rescue JSON::ParserError - info "#{socket.remote_ip} message can't parse" - terminate rescue StandardError => e - info "#{socket.remote_ip} processing error:\n#{e.inspect}" + info "#{headers['host']} processing error:\n#{e.inspect}" terminate - ensure - after_process end def call_action action, *args if Actions.has_key? action - Actions[action].bind(self).call *args + Actions[action].bind(self).call *args else - action_missing action, *args + action_missing action, *args end end def app_finalizer - on_close unless @closed + on_close ensure @socket.close if @socket end end end