Permalink
Browse files

PID file specifyable with -P

  • Loading branch information...
arya committed Jul 21, 2009
1 parent d0713d6 commit 8d3f2e142802ce343c438e99d0faffeecea71c73
Showing with 90 additions and 32 deletions.
  1. +1 −0 lib/pandemic.rb
  2. +49 −32 lib/pandemic/server_side/config.rb
  3. +14 −0 lib/pandemic/server_side/server.rb
  4. +26 −0 test/server_test.rb
View
@@ -6,6 +6,7 @@
require 'yaml'
require 'digest/md5'
require 'logger'
+require 'optparse'
require 'pandemic/util'
require 'pandemic/connection_pool'
@@ -2,19 +2,9 @@ module Pandemic
module ServerSide
class Config
class << self
- attr_accessor :bind_to, :servers, :response_timeout, :fork_for_processor
+ attr_accessor :bind_to, :servers, :response_timeout, :fork_for_processor, :pid_file
def load
- path = extract_config_path
- yaml = YAML.load_file(path)
-
- @server_map = yaml['servers'] || []
- @servers = @server_map.is_a?(Hash) ? @server_map.values : @server_map
- @servers = @servers.collect { |s| s.is_a?(Hash) ? s.keys.first : s }
-
- @response_timeout = (yaml['response_timeout'] || 1).to_f
- @bind_to = extract_bind_to
- @fork_for_processor = yaml['fork_for_processor']
-
+ parse_args!
raise "Interface to bind to is nil." unless @bind_to
end
@@ -23,33 +13,60 @@ def get(*args)
end
private
- def extract_bind_to
- index = ARGV.index('-i')
- index2 = ARGV.index('-a')
+
+ def parse_args!
+ config_path = "pandemic_server.yml"
+ index = nil
+ attach = nil
+
+ @bind_to = nil
+ @pid_file = nil
+ OptionParser.new do |opts|
+ opts.on("-c", "--config [CONFIG-PATH]", "Specify the path to the config file") do |path|
+ config_path = path
+ end
+
+ opts.on("-i", "--index [SERVER-INDEX]", "Specify the index of the server to attach to from the YAML file") do |i|
+ index = i
+ end
- if index && (key = ARGV[index + 1])
- key = key.to_i if @server_map.is_a?(Array)
- server = @server_map[key]
- if server.is_a?(Hash)
+ opts.on("-a", "--attach [SERVER:PORT]", "Specify the host and port to attach to") do |a|
+ attach = a
+ end
+
+ opts.on("-P", "--pid-file [PATH]", "Specify the path to write the PID to") do |path|
+ @pid_file = path
+ end
+ end.parse!
+
+ read_config_file(config_path)
+
+ if index
+ index = index.to_i if @server_map.is_a?(Array)
+ server = @server_map[index]
+
+ @bind_to = if server.is_a?(Hash)
@options = server.values.first # there should only be one
- @server_map[key].keys.first
+ @server_map[index].keys.first
else
server
end
- elsif index2 && (host = ARGV[index2 + 1])
- host
- else
- raise "You must specify which interface to bind to."
+ elsif attach
+ @bind_to = attach
end
+
end
-
- def extract_config_path
- index = ARGV.index('-c')
- if index && (path = ARGV[index + 1])
- path
- else
- "pandemic_server.yml"
- end
+
+ def read_config_file(path)
+ yaml = YAML.load_file(path)
+
+ @server_map = yaml['servers'] || []
+ @servers = @server_map.is_a?(Hash) ? @server_map.values : @server_map
+ @servers = @servers.collect { |s| s.is_a?(Hash) ? s.keys.first : s }
+
+ @response_timeout = (yaml['response_timeout'] || 1).to_f
+
+ @fork_for_processor = yaml['fork_for_processor']
end
end
end
@@ -52,6 +52,7 @@ def start
raise "You must specify a handler" unless @handler
@listener = TCPServer.new(@host, @port)
+ write_pid_file
@running = true
@running_since = Time.now
@@ -72,6 +73,7 @@ def start
end
rescue StopServer
info("Stopping server")
+ remove_pid_file
@listener.close if @listener
@peers.values.each { |p| p.disconnect }
@clients.each {|c| c.close }
@@ -265,6 +267,18 @@ def collect_stats
results
end
+ def remove_pid_file
+ File.unlink(Config.pid_file) if Config.pid_file && File.exists?(Config.pid_file)
+ end
+
+ def write_pid_file
+ return if Config.pid_file.nil?
+ File.open(Config.pid_file,"w") do |f|
+ f.write(Process.pid)
+ File.chmod(0644, Config.pid_file)
+ end
+ end
+
end
end
end
View
@@ -30,6 +30,32 @@ class ServerTest < Test::Unit::TestCase
end
end
+ should "create a pid file" do
+ ignore_threads = Thread.list
+
+ Pandemic::ServerSide::Config.expects(:pid_file).at_least_once.returns("test/pandemic.pid")
+ Pandemic::ServerSide::Config.expects(:servers).at_least_once.returns([])
+ @server = Pandemic::ServerSide::Server.new("localhost:4000")
+
+ @tcpserver = mock()
+ TCPServer.expects(:new).with("localhost", 4000).returns(@tcpserver)
+
+ file = mock()
+ File.expects(:open).with("test/pandemic.pid", "w").yields(file)
+ file.expects(:write).with(Process.pid)
+ File.expects(:chmod)
+ File.expects(:exists?).with("test/pandemic.pid").returns(true)
+ File.expects(:unlink).with("test/pandemic.pid")
+
+ @tcpserver.expects(:accept).once.raises(Pandemic::ServerSide::Server::StopServer)
+
+ @tcpserver.expects(:close)
+
+ @server.handler = mock(:new)
+ @server.start
+ wait_for_threads(ignore_threads)
+ end
+
should "initialize peers" do
Pandemic::ServerSide::Config.expects(:servers).returns(["localhost:4000", "localhost:4001"])
Pandemic::ServerSide::Peer.expects(:new).with("localhost:4001", is_a(Pandemic::ServerSide::Server))

0 comments on commit 8d3f2e1

Please sign in to comment.