X-Git-Url: http://git.sourceforge.jp/view?p=shogi-server%2Fshogi-server.git;a=blobdiff_plain;f=shogi-server;h=750fa6a3e2caf3953f125aca178fcfb3b149e7e1;hp=0533040dfd2b1fbffab6658672ff3d6b093e150e;hb=5c58c6b8062416d280f85c44d0e6903d3fcda929;hpb=3b32488cc2be91d16ce444b5c8f2ba061473bf31 diff --git a/shogi-server b/shogi-server index 0533040..750fa6a 100755 --- a/shogi-server +++ b/shogi-server @@ -28,8 +28,12 @@ $topdir = nil $league = nil $logger = nil +$config = nil $:.unshift File.dirname(__FILE__) require 'shogi_server' +require 'shogi_server/config' +require 'shogi_server/util' +require 'shogi_server/league/floodgate_thread.rb' require 'tempfile' ################################################# @@ -38,6 +42,12 @@ require 'tempfile' ShogiServer.reload +# Return +# - a received string +# - :timeout +# - :exception +# - nil when a socket is closed +# def gets_safe(socket, timeout=nil) if r = select([socket], nil, nil, timeout) return r[0].first.gets @@ -52,36 +62,92 @@ end def usage print <.conf". The file will be re-read once just after a + game starts. + + For example, a floodgate-3600-30 game group requires + floodgate-3600-30.conf. However, for floodgate-900-0 and + floodgate-3600-0, which were default enabled in previous + versions, configuration files are optional if you are happy with + default time settings. + File format is: + Line format: + # This is a comment line + DoW Time + ... + where + DoW := "Sun" | "Mon" | "Tue" | "Wed" | "Thu" | "Fri" | "Sat" | + "Sunday" | "Monday" | "Tuesday" | "Wednesday" | "Thursday" | + "Friday" | "Saturday" + Time := HH:MM + + For example, + Sat 13:00 + Sat 22:00 + Sun 13:00 LICENSE - GPL versoin 2 or later + GPL versoin 2 or later SEE ALSO RELEASE - #{ShogiServer::Release} + #{ShogiServer::Release} REVISION - #{ShogiServer::Revision} + #{ShogiServer::Revision} EOM end @@ -115,9 +181,9 @@ def parse_command_line options = Hash::new parser = GetoptLong.new( ["--daemon", GetoptLong::REQUIRED_ARGUMENT], + ["--floodgate-games", GetoptLong::REQUIRED_ARGUMENT], ["--pid-file", GetoptLong::REQUIRED_ARGUMENT], - ["--player-log-dir", GetoptLong::REQUIRED_ARGUMENT], - ["--floodgate-history", GetoptLong::REQUIRED_ARGUMENT]) + ["--player-log-dir", GetoptLong::REQUIRED_ARGUMENT]) parser.quiet = true begin parser.each_option do |name, arg| @@ -162,37 +228,30 @@ def check_command_line if $options["pid-file"] $options["pid-file"] = File.expand_path($options["pid-file"], $topdir) - unless is_writable_file? $options["pid-file"] + unless ShogiServer::is_writable_file? $options["pid-file"] usage $stderr.puts "Can not create the pid file: %s" % [$options["pid-file"]] exit 4 end end - $options["floodgate-history"] ||= File.join($topdir, "floodgate_history.yaml") - $options["floodgate-history"] = File.expand_path($options["floodgate-history"], $topdir) - unless is_writable_file? $options["floodgate-history"] - usage - $stderr.puts "Can not create the floodgate history file: %s" % [$options["floodgate-history"]] - exit 6 + if $options["floodgate-games"] + names = $options["floodgate-games"].split(",") + new_names = + names.select do |name| + ShogiServer::League::Floodgate::game_name?(name) + end + if names.size != new_names.size + $stderr.puts "Found a wrong Floodgate game: %s" % [names.join(",")] + exit 6 + end + $options["floodgate-games"] = new_names end -end -# See if the file is writable. The file will be created if it does not exist -# yet. -# Return true if the file is writable, otherwise false. -# -def is_writable_file?(file) - begin - open(file, "w") {|fh| } - rescue - return false + if $options["floodgate-history"] + $stderr.puts "WARNING: --floodgate-history has been deprecated." + $options["floodgate-history"] = nil end - unless FileTest.file? file - return false - end - - return true end # See if a file can be created in the directory. @@ -244,7 +303,14 @@ def login_loop(client) player = login = nil while r = select([client], nil, nil, ShogiServer::Login_Time) do - break unless str = r[0].first.gets + str = nil + begin + break unless str = r[0].first.gets + rescue Exception => ex + # It is posssible that the socket causes an error (ex. Errno::ECONNRESET) + log_error("login_loop: #{ex.class}: #{ex.message}\n\t#{ex.backtrace[0]}") + break + end $mutex.lock # guards $league begin str =~ /([\r\n]*)$/ @@ -292,43 +358,11 @@ def setup_watchdog_for_giant_lock end end -def setup_floodgate - return Thread.start do - Thread.pass - floodgate = ShogiServer::League::Floodgate.new($league) - log_message("Flooddgate reloaded. The next match will start at %s." % - [floodgate.next_time]) - - while (true) - begin - diff = floodgate.next_time - Time.now - if diff > 0 - sleep(diff/2) - next - end - $league.reload - floodgate.match_game - floodgate.charge - next_time = floodgate.next_time - $mutex.synchronize do - log_message("Reloading source...") - ShogiServer.reload - end - floodgate = ShogiServer::League::Floodgate.new($league, next_time) - log_message("Floodgate: The next match will start at %s." % - [floodgate.next_time]) - rescue Exception => ex - # ignore errors - log_error("[in Floodgate's thread] #{ex} #{ex.backtrace}") - end - end - end -end - def main $options = parse_command_line check_command_line + $config = ShogiServer::Config.new $options $league = ShogiServer::League.new($topdir) @@ -345,7 +379,7 @@ def main config[:ServerType] = WEBrick::Daemon if $options["daemon"] config[:Logger] = $logger - fg_thread = nil + setup_floodgate = nil config[:StartCallback] = Proc.new do srand @@ -354,7 +388,8 @@ def main end setup_watchdog_for_giant_lock $league.setup_players_database - fg_thread = setup_floodgate + setup_floodgate = ShogiServer::SetupFloodgate.new($options["floodgate-games"]) + setup_floodgate.start end config[:StopCallback] = Proc.new do @@ -368,11 +403,13 @@ def main ["INT", "TERM"].each do |signal| trap(signal) do server.shutdown - fg_thread.kill if fg_thread + setup_floodgate.kill end end - trap("HUP") do - Dependencies.clear + unless (RUBY_PLATFORM.downcase =~ /mswin|mingw|cygwin|bccwin/) + trap("HUP") do + Dependencies.clear + end end $stderr.puts("server started as a deamon [Revision: #{ShogiServer::Revision}]") if $options["daemon"] log_message("server started [Revision: #{ShogiServer::Revision}]")