require 'socket' require 'securerandom' require 'active_model' require 'rubypitaya/core/path' require 'rubypitaya/core/config' require 'rubypitaya/core/session' require 'rubypitaya/core/postman' require 'rubypitaya/core/parameters' require 'rubypitaya/core/routes_base' require 'rubypitaya/core/handler_router' require 'rubypitaya/core/etcd_connector' require 'rubypitaya/core/nats_connector' require 'rubypitaya/core/database_config' require 'rubypitaya/core/redis_connector' require 'rubypitaya/core/instance_holder' require 'rubypitaya/core/database_connector' require 'rubypitaya/core/initializer_content' require 'rubypitaya/core/initializer_broadcast' require 'rubypitaya/core/application_files_importer' module RubyPitaya class Main attr_reader :redis_connector, :config, :bll def initialize @environment_name = ENV.fetch("RUBYPITAYA_ENV") { 'development' } @is_development_environment = @environment_name == 'development' @application_files_importer = ApplicationFilesImporter.new @application_files_importer.import @application_files_importer.auto_reload if @is_development_environment @server_name = ENV['SERVER_NAME'] @service_uuid = SecureRandom.uuid @desktop_name = Socket.gethostname @etcd_prefix = ENV['ETCD_PREFIX'] @etcd_address = ENV['ETCD_URL'] @etcd_lease_seconds = ENV['ETCD_LEASE_SECONDS'].to_i @allow_reconnect = false @etcd_connector = EtcdConnector.new(@service_uuid, @desktop_name, @server_name, @etcd_prefix, @etcd_address, @allow_reconnect, @etcd_lease_seconds) @etcd_connector.connect @nats_address = ENV['NATS_URL'] @nats_connector = NatsConnector.new(@nats_address, @service_uuid, @server_name) @redis_address = ENV['REDIS_URL'] @redis_connector = RedisConnector.new(@redis_address) @redis_connector.connect @database_config = DatabaseConfig.new(@environment_name, Path::DATABASE_CONFIG_PATH) @database_connector = DatabaseConnector.new(@database_config) @database_connector.connect @session = Session.new @postman = Postman.new(@nats_connector) @config = Config.new(Path::APP_CONFIG_FOLDER_PATH) @config.auto_reload if @is_development_environment @bll = InstanceHolder.new @initializer_content = InitializerContent.new(@bll, @redis_connector.redis) @initializer_broadcast = InitializerBroadcast.new @initializer_broadcast.run(@initializer_content) @handler_router = HandlerRouter.new(Path::HANDLERS_FOLDER_PATH, Path::ROUTES_FILE_PATH) run_server end private def run_server @is_shutting_down = false catch :sig_shutdown do Signal.trap("SIGINT") { throw :sig_shutdown } Signal.trap("SIGQUIT") { throw :sig_shutdown } Signal.trap("SIGTERM") { throw :sig_shutdown } puts "Server started!" run_nats_connection end Signal.trap("SIGINT", nil) Signal.trap("SIGQUIT", nil) Signal.trap("SIGTERM", nil) shutdown_server end def shutdown_server return if @is_shutting_down @is_shutting_down = true puts "Server shutting down..." @etcd_connector.disconnect @database_connector.disconnect exit(0) end def run_nats_connection @nats_connector.connect do |request| start_time_seconds = Time.now.to_i message_route = request[:msg][:route] message_data = request[:msg][:data] message_data = JSON.parse(message_data) if message_data.class == String params = Parameters.new(message_data) session_id = request[:session][:id] session_uid = request[:session].fetch(:uid, '') session_data = request[:session][:data] session_data = JSON.parse(session_data) if session_data.class == String frontend_id = request[:frontendID] metadata = request[:metadata] metadata = JSON.parse(metadata) if metadata.class == String @session.update(session_id, session_uid, session_data, metadata, frontend_id) handler_name, action_name = message_route.split('.')[1..-1] puts "request -> route: #{message_route}" puts " -> data: #{message_data}" response = @handler_router.call(handler_name, action_name, @session, @postman, @redis_connector.redis, @config, @bll, params) delta_time_seconds = Time.now.to_i - start_time_seconds puts "response [#{delta_time_seconds}s] -> #{response.to_json}" response end rescue Exception => error puts "ERROR: #{error}" puts error.backtrace run_nats_connection end end end