serverengine 2.0.0pre1-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
 - data/.gitignore +5 -0
 - data/.rspec +2 -0
 - data/.travis.yml +20 -0
 - data/Changelog +122 -0
 - data/Gemfile +2 -0
 - data/LICENSE +202 -0
 - data/NOTICE +3 -0
 - data/README.md +514 -0
 - data/Rakefile +26 -0
 - data/appveyor.yml +24 -0
 - data/examples/server.rb +138 -0
 - data/examples/spawn_worker_script.rb +38 -0
 - data/lib/serverengine.rb +46 -0
 - data/lib/serverengine/blocking_flag.rb +77 -0
 - data/lib/serverengine/command_sender.rb +89 -0
 - data/lib/serverengine/config_loader.rb +82 -0
 - data/lib/serverengine/daemon.rb +233 -0
 - data/lib/serverengine/daemon_logger.rb +135 -0
 - data/lib/serverengine/embedded_server.rb +67 -0
 - data/lib/serverengine/multi_process_server.rb +155 -0
 - data/lib/serverengine/multi_spawn_server.rb +95 -0
 - data/lib/serverengine/multi_thread_server.rb +80 -0
 - data/lib/serverengine/multi_worker_server.rb +150 -0
 - data/lib/serverengine/privilege.rb +57 -0
 - data/lib/serverengine/process_manager.rb +508 -0
 - data/lib/serverengine/server.rb +178 -0
 - data/lib/serverengine/signal_thread.rb +116 -0
 - data/lib/serverengine/signals.rb +31 -0
 - data/lib/serverengine/socket_manager.rb +171 -0
 - data/lib/serverengine/socket_manager_unix.rb +98 -0
 - data/lib/serverengine/socket_manager_win.rb +154 -0
 - data/lib/serverengine/supervisor.rb +313 -0
 - data/lib/serverengine/utils.rb +62 -0
 - data/lib/serverengine/version.rb +3 -0
 - data/lib/serverengine/winsock.rb +128 -0
 - data/lib/serverengine/worker.rb +81 -0
 - data/serverengine.gemspec +37 -0
 - data/spec/blocking_flag_spec.rb +59 -0
 - data/spec/daemon_logger_spec.rb +175 -0
 - data/spec/daemon_spec.rb +169 -0
 - data/spec/multi_process_server_spec.rb +113 -0
 - data/spec/server_worker_context.rb +232 -0
 - data/spec/signal_thread_spec.rb +94 -0
 - data/spec/socket_manager_spec.rb +119 -0
 - data/spec/spec_helper.rb +19 -0
 - data/spec/supervisor_spec.rb +215 -0
 - metadata +184 -0
 
    
        data/Rakefile
    ADDED
    
    | 
         @@ -0,0 +1,26 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #!/usr/bin/env rake
         
     | 
| 
      
 2 
     | 
    
         
            +
            require "bundler/gem_tasks"
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            require 'rake/testtask'
         
     | 
| 
      
 5 
     | 
    
         
            +
            require 'rake/clean'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            require 'rspec/core/rake_task'
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            RSpec::Core::RakeTask.new(:spec)
         
     | 
| 
      
 10 
     | 
    
         
            +
            task :default => [:spec, :build]
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            # 1. update Changelog and lib/serverengine/version.rb
         
     | 
| 
      
 13 
     | 
    
         
            +
            # 2. bundle && bundle exec rake build:all
         
     | 
| 
      
 14 
     | 
    
         
            +
            # 3. release 3 packages built on pkg/ directory
         
     | 
| 
      
 15 
     | 
    
         
            +
            namespace :build do
         
     | 
| 
      
 16 
     | 
    
         
            +
              desc 'Build gems for all platforms'
         
     | 
| 
      
 17 
     | 
    
         
            +
              task :all do
         
     | 
| 
      
 18 
     | 
    
         
            +
                Bundler.with_clean_env do
         
     | 
| 
      
 19 
     | 
    
         
            +
                  %w[ruby x86-mingw32 x64-mingw32].each do |name|
         
     | 
| 
      
 20 
     | 
    
         
            +
                    ENV['GEM_BUILD_FAKE_PLATFORM'] = name
         
     | 
| 
      
 21 
     | 
    
         
            +
                    Rake::Task["build"].execute
         
     | 
| 
      
 22 
     | 
    
         
            +
                  end
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
              end
         
     | 
| 
      
 25 
     | 
    
         
            +
            end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
    
        data/appveyor.yml
    ADDED
    
    | 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            ---
         
     | 
| 
      
 2 
     | 
    
         
            +
            install:
         
     | 
| 
      
 3 
     | 
    
         
            +
              - SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
         
     | 
| 
      
 4 
     | 
    
         
            +
              - ruby --version
         
     | 
| 
      
 5 
     | 
    
         
            +
              - gem --version
         
     | 
| 
      
 6 
     | 
    
         
            +
              - bundle install
         
     | 
| 
      
 7 
     | 
    
         
            +
            build: off
         
     | 
| 
      
 8 
     | 
    
         
            +
            test_script:
         
     | 
| 
      
 9 
     | 
    
         
            +
              - bundle exec rake -rdevkit
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            environment:
         
     | 
| 
      
 12 
     | 
    
         
            +
              matrix:
         
     | 
| 
      
 13 
     | 
    
         
            +
                - ruby_version: "23-x64"
         
     | 
| 
      
 14 
     | 
    
         
            +
                  devkit: C:\Ruby23-x64\DevKit
         
     | 
| 
      
 15 
     | 
    
         
            +
                - ruby_version: "23"
         
     | 
| 
      
 16 
     | 
    
         
            +
                  devkit: C:\Ruby23\DevKit
         
     | 
| 
      
 17 
     | 
    
         
            +
                - ruby_version: "22-x64"
         
     | 
| 
      
 18 
     | 
    
         
            +
                  devkit: C:\Ruby23-x64\DevKit
         
     | 
| 
      
 19 
     | 
    
         
            +
                - ruby_version: "22"
         
     | 
| 
      
 20 
     | 
    
         
            +
                  devkit: C:\Ruby23\DevKit
         
     | 
| 
      
 21 
     | 
    
         
            +
                - ruby_version: "21-x64"
         
     | 
| 
      
 22 
     | 
    
         
            +
                  devkit: C:\Ruby23-x64\DevKit
         
     | 
| 
      
 23 
     | 
    
         
            +
                - ruby_version: "21"
         
     | 
| 
      
 24 
     | 
    
         
            +
                  devkit: C:\Ruby23\DevKit
         
     | 
    
        data/examples/server.rb
    ADDED
    
    | 
         @@ -0,0 +1,138 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'serverengine'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'json'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'optparse'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            # This is a script to run ServerEngine and SocketManager as a real process.
         
     | 
| 
      
 7 
     | 
    
         
            +
            # bundle exec ruby example/server.rb [-t TYPE] [-w NUM]
         
     | 
| 
      
 8 
     | 
    
         
            +
            # available type of workers are: embedded(default), process, thread, spawn
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            foreground = false
         
     | 
| 
      
 11 
     | 
    
         
            +
            supervisor = false
         
     | 
| 
      
 12 
     | 
    
         
            +
            worker_type = nil
         
     | 
| 
      
 13 
     | 
    
         
            +
            workers = 4
         
     | 
| 
      
 14 
     | 
    
         
            +
            exit_with_code = nil
         
     | 
| 
      
 15 
     | 
    
         
            +
            exit_at_seconds = 5
         
     | 
| 
      
 16 
     | 
    
         
            +
            exit_at_random = false
         
     | 
| 
      
 17 
     | 
    
         
            +
            stop_immediately_at_exit = false
         
     | 
| 
      
 18 
     | 
    
         
            +
            unrecoverable_exit_codes = []
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            opt = OptionParser.new
         
     | 
| 
      
 21 
     | 
    
         
            +
            opt.on('-f'){ foreground = true }
         
     | 
| 
      
 22 
     | 
    
         
            +
            opt.on('-x'){ supervisor = true }
         
     | 
| 
      
 23 
     | 
    
         
            +
            opt.on('-t TYPE'){|v| worker_type = v }
         
     | 
| 
      
 24 
     | 
    
         
            +
            opt.on('-w NUM'){|v| workers = v.to_i }
         
     | 
| 
      
 25 
     | 
    
         
            +
            opt.on('-e NUM'){|v| exit_with_code = v.to_i }
         
     | 
| 
      
 26 
     | 
    
         
            +
            opt.on('-s NUM'){|v| exit_at_seconds = v.to_i }
         
     | 
| 
      
 27 
     | 
    
         
            +
            opt.on('-r'){ exit_at_random = true }
         
     | 
| 
      
 28 
     | 
    
         
            +
            opt.on('-i'){ stop_immediately_at_exit = true }
         
     | 
| 
      
 29 
     | 
    
         
            +
            opt.on('-u NUM'){|v| unrecoverable_exit_codes << v.to_i }
         
     | 
| 
      
 30 
     | 
    
         
            +
            opt.parse!(ARGV)
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            if exit_with_code
         
     | 
| 
      
 33 
     | 
    
         
            +
              ENV['EXIT_WITH_CODE'] = exit_with_code.to_s
         
     | 
| 
      
 34 
     | 
    
         
            +
              ENV['EXIT_AT_SECONDS'] = exit_at_seconds.to_s
         
     | 
| 
      
 35 
     | 
    
         
            +
              if exit_at_random
         
     | 
| 
      
 36 
     | 
    
         
            +
                ENV['EXIT_AT_RANDOM'] = 'true'
         
     | 
| 
      
 37 
     | 
    
         
            +
              end
         
     | 
| 
      
 38 
     | 
    
         
            +
            end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
            module MyServer
         
     | 
| 
      
 41 
     | 
    
         
            +
              attr_reader :socket_manager_path
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
              def before_run
         
     | 
| 
      
 44 
     | 
    
         
            +
                @socket_manager_path = ServerEngine::SocketManager::Server.generate_path
         
     | 
| 
      
 45 
     | 
    
         
            +
                @socket_manager_server = ServerEngine::SocketManager::Server.open(@socket_manager_path)
         
     | 
| 
      
 46 
     | 
    
         
            +
              rescue Exception => e
         
     | 
| 
      
 47 
     | 
    
         
            +
                logger.error "unexpected error in server, class #{e.class}: #{e.message}"
         
     | 
| 
      
 48 
     | 
    
         
            +
                raise
         
     | 
| 
      
 49 
     | 
    
         
            +
              end
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
              def after_run
         
     | 
| 
      
 52 
     | 
    
         
            +
                logger.info "Server stopped."
         
     | 
| 
      
 53 
     | 
    
         
            +
                @socket_manager_server.close
         
     | 
| 
      
 54 
     | 
    
         
            +
              end
         
     | 
| 
      
 55 
     | 
    
         
            +
            end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
            module MyWorker
         
     | 
| 
      
 58 
     | 
    
         
            +
              def initialize
         
     | 
| 
      
 59 
     | 
    
         
            +
                @stop = false
         
     | 
| 
      
 60 
     | 
    
         
            +
                @socket_manager = ServerEngine::SocketManager::Client.new(server.socket_manager_path)
         
     | 
| 
      
 61 
     | 
    
         
            +
                @exit_with_code = ENV.key?('EXIT_WITH_CODE') ? ENV['EXIT_WITH_CODE'].to_i : nil
         
     | 
| 
      
 62 
     | 
    
         
            +
                @exit_at_seconds = ENV.key?('EXIT_AT_SECONDS') ? ENV['EXIT_AT_SECONDS'].to_i : nil
         
     | 
| 
      
 63 
     | 
    
         
            +
                @exit_at_random = ENV.key?('EXIT_AT_RANDOM')
         
     | 
| 
      
 64 
     | 
    
         
            +
              end
         
     | 
| 
      
 65 
     | 
    
         
            +
             
     | 
| 
      
 66 
     | 
    
         
            +
              def main
         
     | 
| 
      
 67 
     | 
    
         
            +
                # test to listen the same port
         
     | 
| 
      
 68 
     | 
    
         
            +
                logger.info "Starting to run Worker."
         
     | 
| 
      
 69 
     | 
    
         
            +
                _listen_sock = @socket_manager.listen_tcp('0.0.0.0', 12345)
         
     | 
| 
      
 70 
     | 
    
         
            +
                stop_at = if @exit_with_code
         
     | 
| 
      
 71 
     | 
    
         
            +
                            stop_seconds = @exit_at_random ? rand(@exit_at_seconds) : @exit_at_seconds
         
     | 
| 
      
 72 
     | 
    
         
            +
                            logger.info "Stop #{stop_seconds} seconds later with code #{@exit_with_code}."
         
     | 
| 
      
 73 
     | 
    
         
            +
                            Time.now + stop_seconds
         
     | 
| 
      
 74 
     | 
    
         
            +
                          else
         
     | 
| 
      
 75 
     | 
    
         
            +
                            nil
         
     | 
| 
      
 76 
     | 
    
         
            +
                          end
         
     | 
| 
      
 77 
     | 
    
         
            +
                until @stop
         
     | 
| 
      
 78 
     | 
    
         
            +
                  if stop_at && Time.now >= stop_at
         
     | 
| 
      
 79 
     | 
    
         
            +
                    logger.info "Exitting with code #{@exit_with_code}"
         
     | 
| 
      
 80 
     | 
    
         
            +
                    exit! @exit_with_code
         
     | 
| 
      
 81 
     | 
    
         
            +
                  end
         
     | 
| 
      
 82 
     | 
    
         
            +
                  logger.info "Awesome work!"
         
     | 
| 
      
 83 
     | 
    
         
            +
                  sleep 1
         
     | 
| 
      
 84 
     | 
    
         
            +
                end
         
     | 
| 
      
 85 
     | 
    
         
            +
                logger.info "Exitting"
         
     | 
| 
      
 86 
     | 
    
         
            +
              rescue Exception => e
         
     | 
| 
      
 87 
     | 
    
         
            +
                logger.warn "unexpected error, class #{e.class}: #{e.message}"
         
     | 
| 
      
 88 
     | 
    
         
            +
                raise
         
     | 
| 
      
 89 
     | 
    
         
            +
              end
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
              def stop
         
     | 
| 
      
 92 
     | 
    
         
            +
                @stop = true
         
     | 
| 
      
 93 
     | 
    
         
            +
              end
         
     | 
| 
      
 94 
     | 
    
         
            +
            end
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
            module MySpawnWorker
         
     | 
| 
      
 97 
     | 
    
         
            +
              def spawn(process_manager)
         
     | 
| 
      
 98 
     | 
    
         
            +
                env = {
         
     | 
| 
      
 99 
     | 
    
         
            +
                  'SERVER_ENGINE_CONFIG' => config.to_json,
         
     | 
| 
      
 100 
     | 
    
         
            +
                  'SERVER_ENGINE_SOCKET_MANAGER_PATH' => server.socket_manager_path,
         
     | 
| 
      
 101 
     | 
    
         
            +
                }
         
     | 
| 
      
 102 
     | 
    
         
            +
                if ENV['EXIT_WITH_CODE']
         
     | 
| 
      
 103 
     | 
    
         
            +
                  env['EXIT_WITH_CODE'] = ENV['EXIT_WITH_CODE']
         
     | 
| 
      
 104 
     | 
    
         
            +
                  env['EXIT_AT_SECONDS'] = ENV['EXIT_AT_SECONDS']
         
     | 
| 
      
 105 
     | 
    
         
            +
                  if ENV['EXIT_AT_RANDOM']
         
     | 
| 
      
 106 
     | 
    
         
            +
                    env['EXIT_AT_RANDOM'] = 'true'
         
     | 
| 
      
 107 
     | 
    
         
            +
                  end
         
     | 
| 
      
 108 
     | 
    
         
            +
                end
         
     | 
| 
      
 109 
     | 
    
         
            +
                process_manager.spawn(env, "ruby", File.expand_path("../spawn_worker_script.rb", __FILE__))
         
     | 
| 
      
 110 
     | 
    
         
            +
              rescue Exception => e
         
     | 
| 
      
 111 
     | 
    
         
            +
                logger.error "unexpected error, class #{e.class}: #{e.message}"
         
     | 
| 
      
 112 
     | 
    
         
            +
                raise
         
     | 
| 
      
 113 
     | 
    
         
            +
              end
         
     | 
| 
      
 114 
     | 
    
         
            +
            end
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
            opts = {
         
     | 
| 
      
 117 
     | 
    
         
            +
              daemonize: !foreground,
         
     | 
| 
      
 118 
     | 
    
         
            +
              daemon_process_name: 'mydaemon',
         
     | 
| 
      
 119 
     | 
    
         
            +
              supervisor: supervisor,
         
     | 
| 
      
 120 
     | 
    
         
            +
              log: 'myserver.log',
         
     | 
| 
      
 121 
     | 
    
         
            +
              pid_path: 'myserver.pid',
         
     | 
| 
      
 122 
     | 
    
         
            +
              worker_type: worker_type,
         
     | 
| 
      
 123 
     | 
    
         
            +
              workers: workers,
         
     | 
| 
      
 124 
     | 
    
         
            +
            }
         
     | 
| 
      
 125 
     | 
    
         
            +
            if stop_immediately_at_exit
         
     | 
| 
      
 126 
     | 
    
         
            +
              opts[:stop_immediately_at_unrecoverable_exit] = true
         
     | 
| 
      
 127 
     | 
    
         
            +
            end
         
     | 
| 
      
 128 
     | 
    
         
            +
            unless unrecoverable_exit_codes.empty?
         
     | 
| 
      
 129 
     | 
    
         
            +
              opts[:unrecoverable_exit_codes] = unrecoverable_exit_codes
         
     | 
| 
      
 130 
     | 
    
         
            +
            end
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
            worker_klass = MyWorker
         
     | 
| 
      
 133 
     | 
    
         
            +
            if worker_type == 'spawn'
         
     | 
| 
      
 134 
     | 
    
         
            +
              worker_klass = MySpawnWorker
         
     | 
| 
      
 135 
     | 
    
         
            +
            end
         
     | 
| 
      
 136 
     | 
    
         
            +
            se = ServerEngine.create(MyServer, worker_klass, opts)
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
            se.run
         
     | 
| 
         @@ -0,0 +1,38 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            $LOAD_PATH.unshift File.expand_path("../..", __FILE__)
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            require 'serverengine'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'json'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
            begin
         
     | 
| 
      
 7 
     | 
    
         
            +
              conf = JSON.parse(ENV['SERVER_ENGINE_CONFIG'], symbolize_names: true)
         
     | 
| 
      
 8 
     | 
    
         
            +
              logger = ServerEngine::DaemonLogger.new(conf[:log] || STDOUT, conf)
         
     | 
| 
      
 9 
     | 
    
         
            +
              logger.info "Starting to run Worker."
         
     | 
| 
      
 10 
     | 
    
         
            +
              socket_manager = ServerEngine::SocketManager::Client.new(ENV['SERVER_ENGINE_SOCKET_MANAGER_PATH'])
         
     | 
| 
      
 11 
     | 
    
         
            +
              exit_with_code = ENV.key?('EXIT_WITH_CODE') ? ENV['EXIT_WITH_CODE'].to_i : nil
         
     | 
| 
      
 12 
     | 
    
         
            +
              exit_at_seconds = ENV.key?('EXIT_AT_SECONDS') ? ENV['EXIT_AT_SECONDS'].to_i : nil
         
     | 
| 
      
 13 
     | 
    
         
            +
              exit_at_random = ENV.key?('EXIT_AT_RANDOM')
         
     | 
| 
      
 14 
     | 
    
         
            +
              stop_at = if exit_with_code
         
     | 
| 
      
 15 
     | 
    
         
            +
                          stop_seconds = exit_at_random ? rand(exit_at_seconds) : exit_at_seconds
         
     | 
| 
      
 16 
     | 
    
         
            +
                          logger.info "Stop #{stop_seconds} seconds later with code #{exit_with_code}."
         
     | 
| 
      
 17 
     | 
    
         
            +
                          Time.now + stop_seconds
         
     | 
| 
      
 18 
     | 
    
         
            +
                        else
         
     | 
| 
      
 19 
     | 
    
         
            +
                          nil
         
     | 
| 
      
 20 
     | 
    
         
            +
                        end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              @stop = false
         
     | 
| 
      
 23 
     | 
    
         
            +
              trap(:SIGTERM) { @stop = true }
         
     | 
| 
      
 24 
     | 
    
         
            +
              trap(:SIGINT) { @stop = true }
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              _listen_sock = socket_manager.listen_tcp('0.0.0.0', 12345)
         
     | 
| 
      
 27 
     | 
    
         
            +
              until @stop
         
     | 
| 
      
 28 
     | 
    
         
            +
                if stop_at && Time.now >= stop_at
         
     | 
| 
      
 29 
     | 
    
         
            +
                  logger.info "Exitting with code #{exit_with_code}"
         
     | 
| 
      
 30 
     | 
    
         
            +
                  exit! exit_with_code
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
                logger.info 'Awesome work!'
         
     | 
| 
      
 33 
     | 
    
         
            +
                sleep 1
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
              logger.info 'Exitting'
         
     | 
| 
      
 36 
     | 
    
         
            +
            rescue Exception => e
         
     | 
| 
      
 37 
     | 
    
         
            +
              logger.error "unexpected error in spawn worker, class #{e.class}: #{e.message}"
         
     | 
| 
      
 38 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/serverengine.rb
    ADDED
    
    | 
         @@ -0,0 +1,46 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #
         
     | 
| 
      
 2 
     | 
    
         
            +
            # ServerEngine
         
     | 
| 
      
 3 
     | 
    
         
            +
            #
         
     | 
| 
      
 4 
     | 
    
         
            +
            # Copyright (C) 2012-2013 Sadayuki Furuhashi
         
     | 
| 
      
 5 
     | 
    
         
            +
            #
         
     | 
| 
      
 6 
     | 
    
         
            +
            #    Licensed under the Apache License, Version 2.0 (the "License");
         
     | 
| 
      
 7 
     | 
    
         
            +
            #    you may not use this file except in compliance with the License.
         
     | 
| 
      
 8 
     | 
    
         
            +
            #    You may obtain a copy of the License at
         
     | 
| 
      
 9 
     | 
    
         
            +
            #
         
     | 
| 
      
 10 
     | 
    
         
            +
            #        http://www.apache.org/licenses/LICENSE-2.0
         
     | 
| 
      
 11 
     | 
    
         
            +
            #
         
     | 
| 
      
 12 
     | 
    
         
            +
            #    Unless required by applicable law or agreed to in writing, software
         
     | 
| 
      
 13 
     | 
    
         
            +
            #    distributed under the License is distributed on an "AS IS" BASIS,
         
     | 
| 
      
 14 
     | 
    
         
            +
            #    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
         
     | 
| 
      
 15 
     | 
    
         
            +
            #    See the License for the specific language governing permissions and
         
     | 
| 
      
 16 
     | 
    
         
            +
            #    limitations under the License.
         
     | 
| 
      
 17 
     | 
    
         
            +
            #
         
     | 
| 
      
 18 
     | 
    
         
            +
            module ServerEngine
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
              require 'sigdump'
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              require 'serverengine/version'
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
              require 'serverengine/utils' # ServerEngine.windows? and other util methods
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
              require 'serverengine/daemon'
         
     | 
| 
      
 27 
     | 
    
         
            +
              require 'serverengine/supervisor'
         
     | 
| 
      
 28 
     | 
    
         
            +
              require 'serverengine/server'
         
     | 
| 
      
 29 
     | 
    
         
            +
              require 'serverengine/worker'
         
     | 
| 
      
 30 
     | 
    
         
            +
              require 'serverengine/socket_manager'
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
              def self.create(server_module, worker_module, load_config_proc={}, &block)
         
     | 
| 
      
 33 
     | 
    
         
            +
                Daemon.new(server_module, worker_module, load_config_proc, &block)
         
     | 
| 
      
 34 
     | 
    
         
            +
              end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
              def self.ruby_bin_path
         
     | 
| 
      
 37 
     | 
    
         
            +
                if ServerEngine.windows?
         
     | 
| 
      
 38 
     | 
    
         
            +
                  require 'windows/library'
         
     | 
| 
      
 39 
     | 
    
         
            +
                  ruby_path = "\0" * 256
         
     | 
| 
      
 40 
     | 
    
         
            +
                  Windows::Library::GetModuleFileName.call(0, ruby_path, 256)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  return ruby_path.rstrip.gsub(/\\/, '/')
         
     | 
| 
      
 42 
     | 
    
         
            +
                else
         
     | 
| 
      
 43 
     | 
    
         
            +
                  return File.join(RbConfig::CONFIG["bindir"], RbConfig::CONFIG["RUBY_INSTALL_NAME"]) + RbConfig::CONFIG["EXEEXT"]
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
              end
         
     | 
| 
      
 46 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,77 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #
         
     | 
| 
      
 2 
     | 
    
         
            +
            # ServerEngine
         
     | 
| 
      
 3 
     | 
    
         
            +
            #
         
     | 
| 
      
 4 
     | 
    
         
            +
            # Copyright (C) 2012-2013 Sadayuki Furuhashi
         
     | 
| 
      
 5 
     | 
    
         
            +
            #
         
     | 
| 
      
 6 
     | 
    
         
            +
            #    Licensed under the Apache License, Version 2.0 (the "License");
         
     | 
| 
      
 7 
     | 
    
         
            +
            #    you may not use this file except in compliance with the License.
         
     | 
| 
      
 8 
     | 
    
         
            +
            #    You may obtain a copy of the License at
         
     | 
| 
      
 9 
     | 
    
         
            +
            #
         
     | 
| 
      
 10 
     | 
    
         
            +
            #        http://www.apache.org/licenses/LICENSE-2.0
         
     | 
| 
      
 11 
     | 
    
         
            +
            #
         
     | 
| 
      
 12 
     | 
    
         
            +
            #    Unless required by applicable law or agreed to in writing, software
         
     | 
| 
      
 13 
     | 
    
         
            +
            #    distributed under the License is distributed on an "AS IS" BASIS,
         
     | 
| 
      
 14 
     | 
    
         
            +
            #    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
         
     | 
| 
      
 15 
     | 
    
         
            +
            #    See the License for the specific language governing permissions and
         
     | 
| 
      
 16 
     | 
    
         
            +
            #    limitations under the License.
         
     | 
| 
      
 17 
     | 
    
         
            +
            #
         
     | 
| 
      
 18 
     | 
    
         
            +
            require 'thread'
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            module ServerEngine
         
     | 
| 
      
 21 
     | 
    
         
            +
              class BlockingFlag
         
     | 
| 
      
 22 
     | 
    
         
            +
                def initialize
         
     | 
| 
      
 23 
     | 
    
         
            +
                  @set = false
         
     | 
| 
      
 24 
     | 
    
         
            +
                  @mutex = Mutex.new
         
     | 
| 
      
 25 
     | 
    
         
            +
                  @cond = ConditionVariable.new
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                def set!
         
     | 
| 
      
 29 
     | 
    
         
            +
                  toggled = false
         
     | 
| 
      
 30 
     | 
    
         
            +
                  @mutex.synchronize do
         
     | 
| 
      
 31 
     | 
    
         
            +
                    unless @set
         
     | 
| 
      
 32 
     | 
    
         
            +
                      @set = true
         
     | 
| 
      
 33 
     | 
    
         
            +
                      toggled = true
         
     | 
| 
      
 34 
     | 
    
         
            +
                    end
         
     | 
| 
      
 35 
     | 
    
         
            +
                    @cond.broadcast
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
                  return toggled
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                def reset!
         
     | 
| 
      
 41 
     | 
    
         
            +
                  toggled = false
         
     | 
| 
      
 42 
     | 
    
         
            +
                  @mutex.synchronize do
         
     | 
| 
      
 43 
     | 
    
         
            +
                    if @set
         
     | 
| 
      
 44 
     | 
    
         
            +
                      @set = false
         
     | 
| 
      
 45 
     | 
    
         
            +
                      toggled = true
         
     | 
| 
      
 46 
     | 
    
         
            +
                    end
         
     | 
| 
      
 47 
     | 
    
         
            +
                    @cond.broadcast
         
     | 
| 
      
 48 
     | 
    
         
            +
                  end
         
     | 
| 
      
 49 
     | 
    
         
            +
                  return toggled
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                def set?
         
     | 
| 
      
 53 
     | 
    
         
            +
                  @set
         
     | 
| 
      
 54 
     | 
    
         
            +
                end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                def wait_for_set(timeout=nil)
         
     | 
| 
      
 57 
     | 
    
         
            +
                  @mutex.synchronize do
         
     | 
| 
      
 58 
     | 
    
         
            +
                    unless @set
         
     | 
| 
      
 59 
     | 
    
         
            +
                      @cond.wait(@mutex, timeout)
         
     | 
| 
      
 60 
     | 
    
         
            +
                    end
         
     | 
| 
      
 61 
     | 
    
         
            +
                    return @set
         
     | 
| 
      
 62 
     | 
    
         
            +
                  end
         
     | 
| 
      
 63 
     | 
    
         
            +
                end
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                alias_method :wait, :wait_for_set
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                def wait_for_reset(timeout=nil)
         
     | 
| 
      
 68 
     | 
    
         
            +
                  @mutex.synchronize do
         
     | 
| 
      
 69 
     | 
    
         
            +
                    if @set
         
     | 
| 
      
 70 
     | 
    
         
            +
                      @cond.wait(@mutex, timeout)
         
     | 
| 
      
 71 
     | 
    
         
            +
                    end
         
     | 
| 
      
 72 
     | 
    
         
            +
                    return !@set
         
     | 
| 
      
 73 
     | 
    
         
            +
                  end
         
     | 
| 
      
 74 
     | 
    
         
            +
                end
         
     | 
| 
      
 75 
     | 
    
         
            +
              end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,89 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            #
         
     | 
| 
      
 2 
     | 
    
         
            +
            # ServerEngine
         
     | 
| 
      
 3 
     | 
    
         
            +
            #
         
     | 
| 
      
 4 
     | 
    
         
            +
            # Copyright (C) 2012-2013 FURUHASHI Sadayuki
         
     | 
| 
      
 5 
     | 
    
         
            +
            #
         
     | 
| 
      
 6 
     | 
    
         
            +
            #    Licensed under the Apache License, Version 2.0 (the "License");
         
     | 
| 
      
 7 
     | 
    
         
            +
            #    you may not use this file except in compliance with the License.
         
     | 
| 
      
 8 
     | 
    
         
            +
            #    You may obtain a copy of the License at
         
     | 
| 
      
 9 
     | 
    
         
            +
            #
         
     | 
| 
      
 10 
     | 
    
         
            +
            #        http://www.apache.org/licenses/LICENSE-2.0
         
     | 
| 
      
 11 
     | 
    
         
            +
            #
         
     | 
| 
      
 12 
     | 
    
         
            +
            #    Unless required by applicable law or agreed to in writing, software
         
     | 
| 
      
 13 
     | 
    
         
            +
            #    distributed under the License is distributed on an "AS IS" BASIS,
         
     | 
| 
      
 14 
     | 
    
         
            +
            #    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
         
     | 
| 
      
 15 
     | 
    
         
            +
            #    See the License for the specific language governing permissions and
         
     | 
| 
      
 16 
     | 
    
         
            +
            #    limitations under the License.
         
     | 
| 
      
 17 
     | 
    
         
            +
            #
         
     | 
| 
      
 18 
     | 
    
         
            +
            require 'serverengine/signals'
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            module ServerEngine
         
     | 
| 
      
 21 
     | 
    
         
            +
              module CommandSender
         
     | 
| 
      
 22 
     | 
    
         
            +
                # requires send_signal method or @pid
         
     | 
| 
      
 23 
     | 
    
         
            +
                module Signal
         
     | 
| 
      
 24 
     | 
    
         
            +
                  private
         
     | 
| 
      
 25 
     | 
    
         
            +
                  def _stop(graceful)
         
     | 
| 
      
 26 
     | 
    
         
            +
                    _send_signal(!ServerEngine.windows? && graceful ? Signals::GRACEFUL_STOP : Signals::IMMEDIATE_STOP)
         
     | 
| 
      
 27 
     | 
    
         
            +
                  end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                  def _restart(graceful)
         
     | 
| 
      
 30 
     | 
    
         
            +
                    _send_signal(graceful ? Signals::GRACEFUL_RESTART : Signals::IMMEDIATE_RESTART)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  def _reload
         
     | 
| 
      
 34 
     | 
    
         
            +
                    _send_signal(Signals::RELOAD)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                  def _detach
         
     | 
| 
      
 38 
     | 
    
         
            +
                    _send_signal(Signals::DETACH)
         
     | 
| 
      
 39 
     | 
    
         
            +
                  end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                  def _dump
         
     | 
| 
      
 42 
     | 
    
         
            +
                    _send_signal(Signals::DUMP)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                  def _send_signal(sig)
         
     | 
| 
      
 46 
     | 
    
         
            +
                    if respond_to?(:send_signal, true)
         
     | 
| 
      
 47 
     | 
    
         
            +
                      send_signal(sig)
         
     | 
| 
      
 48 
     | 
    
         
            +
                    else
         
     | 
| 
      
 49 
     | 
    
         
            +
                      Process.kill(sig, @pid)
         
     | 
| 
      
 50 
     | 
    
         
            +
                    end
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
                end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                # requires @command_sender_pipe
         
     | 
| 
      
 55 
     | 
    
         
            +
                module Pipe
         
     | 
| 
      
 56 
     | 
    
         
            +
                  private
         
     | 
| 
      
 57 
     | 
    
         
            +
                  def _stop(graceful)
         
     | 
| 
      
 58 
     | 
    
         
            +
                    begin
         
     | 
| 
      
 59 
     | 
    
         
            +
                      _send_command(graceful ? "GRACEFUL_STOP" : "IMMEDIATE_STOP")
         
     | 
| 
      
 60 
     | 
    
         
            +
                    rescue Errno::EPIPE
         
     | 
| 
      
 61 
     | 
    
         
            +
                      # already stopped, then nothing to do
         
     | 
| 
      
 62 
     | 
    
         
            +
                    ensure
         
     | 
| 
      
 63 
     | 
    
         
            +
                      @command_sender_pipe.close rescue nil
         
     | 
| 
      
 64 
     | 
    
         
            +
                      @command_sender_pipe = nil
         
     | 
| 
      
 65 
     | 
    
         
            +
                    end
         
     | 
| 
      
 66 
     | 
    
         
            +
                  end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                  def _restart(graceful)
         
     | 
| 
      
 69 
     | 
    
         
            +
                    _send_command(graceful ? "GRACEFUL_RESTART" : "IMMEDIATE_RESTART")
         
     | 
| 
      
 70 
     | 
    
         
            +
                  end
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                  def _reload
         
     | 
| 
      
 73 
     | 
    
         
            +
                    _send_command("RELOAD")
         
     | 
| 
      
 74 
     | 
    
         
            +
                  end
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
                  def _detach
         
     | 
| 
      
 77 
     | 
    
         
            +
                    _send_command("DETACH")
         
     | 
| 
      
 78 
     | 
    
         
            +
                  end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                  def _dump
         
     | 
| 
      
 81 
     | 
    
         
            +
                    _send_command("DUMP")
         
     | 
| 
      
 82 
     | 
    
         
            +
                  end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
                  def _send_command(cmd)
         
     | 
| 
      
 85 
     | 
    
         
            +
                    @command_sender_pipe.write cmd + "\n"
         
     | 
| 
      
 86 
     | 
    
         
            +
                  end
         
     | 
| 
      
 87 
     | 
    
         
            +
                end
         
     | 
| 
      
 88 
     | 
    
         
            +
              end
         
     | 
| 
      
 89 
     | 
    
         
            +
            end
         
     |