• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

shogi-server source


Commit MetaInfo

Revisione37932a0d2387227928808ec86f49362ae29f9ea (tree)
Time2020-10-02 01:36:08
AuthorMizar <mizar.jp@gmai...>
CommiterMizar

Log Message

tcp_keepalive

Change Summary

Incremental Difference

--- a/bin/usiToCsa.rb
+++ b/bin/usiToCsa.rb
@@ -28,6 +28,7 @@ $:.unshift(File.join(File.dirname(File.expand_path(__FILE__)), ".."))
2828 require 'shogi_server'
2929 require 'logger'
3030 require 'socket'
31+require 'timeout'
3132
3233 # Global variables
3334
@@ -105,7 +106,12 @@ def parse_command_line
105106 ["--options", GetoptLong::REQUIRED_ARGUMENT],
106107 ["--password", GetoptLong::REQUIRED_ARGUMENT],
107108 ["--ponder", GetoptLong::NO_ARGUMENT],
108- ["--port", GetoptLong::REQUIRED_ARGUMENT])
109+ ["--port", GetoptLong::REQUIRED_ARGUMENT],
110+ ["--ignoremultiselect", GetoptLong::NO_ARGUMENT],
111+ ["--tcpkeepalive", GetoptLong::REQUIRED_ARGUMENT],
112+ ["--tcpkeepalive-idle", GetoptLong::REQUIRED_ARGUMENT],
113+ ["--tcpkeepalive-intvl", GetoptLong::REQUIRED_ARGUMENT],
114+ ["--tcpkeepalive-cnt", GetoptLong::REQUIRED_ARGUMENT])
109115 parser.quiet = true
110116 begin
111117 parser.each_option do |name, arg|
@@ -132,6 +138,15 @@ def parse_command_line
132138 options[:ponder] ||= ENV["PONDER"] || false
133139 options[:port] ||= ENV["PORT"] || 4081
134140 options[:port] = options[:port].to_i
141+ options[:ignoremultiselect] ||= ENV["IGNORE_MULTISELECT"] || false
142+ options[:tcpkeepalive] ||= ENV["TCPKEEPALIVE"] || 0
143+ options[:tcpkeepalive] = options[:tcpkeepalive].to_i
144+ options[:tcpkeepalive_idle] ||= ENV["TCPKEEPALIVE_IDLE"] || 50
145+ options[:tcpkeepalive_idle] = options[:tcpkeepalive_idle].to_i
146+ options[:tcpkeepalive_intvl] ||= ENV["TCPKEEPALIVE_INTVL"] || 5
147+ options[:tcpkeepalive_intvl] = options[:tcpkeepalive_intvl].to_i
148+ options[:tcpkeepalive_cnt] ||= ENV["TCPKEEPALIVE_CNT"] || 9
149+ options[:tcpkeepalive_cnt] = options[:tcpkeepalive_cnt].to_i
135150
136151 return options
137152 end
@@ -424,7 +439,14 @@ class BridgeState
424439 throw "Bad state at event_engine_recv: #@state"
425440 end
426441
427- str = $server.gets
442+ str = nil
443+ begin
444+ Timeout.timeout(0.001){
445+ str = $server.gets
446+ }
447+ rescue Timeout::Error
448+ $logger.error "event_server_recv timeout"
449+ end
428450 return if str.nil? || str.strip.empty?
429451 log_server_recv str
430452
@@ -567,6 +589,30 @@ def login
567589 begin
568590 $server = TCPSocket.open($options[:host], $options[:port])
569591 $server.sync = true
592+ if $options[:tcpkeepalive] > 0 &&
593+ Socket.const_defined?(:SOL_SOCKET) &&
594+ Socket.const_defined?(:SO_KEEPALIVE) &&
595+ Socket.const_defined?(:IPPROTO_TCP)
596+ $server.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true)
597+ if Socket.const_defined?(:TCP_KEEPIDLE) &&
598+ Socket.const_defined?(:TCP_KEEPINTVL) &&
599+ Socket.const_defined?(:TCP_KEEPCNT)
600+ $server.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_KEEPIDLE, $options[:tcpkeepalive_idle])
601+ $server.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_KEEPINTVL, $options[:tcpkeepalive_intvl])
602+ $server.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_KEEPCNT, $options[:tcpkeepalive_cnt])
603+ elsif RUBY_PLATFORM.downcase =~ /mswin|mingw|cygwin|bccwin/
604+ # Windows 10 (1709 or later) ws2ipdef.h
605+ # https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-tcp-socket-options
606+ $server.setsockopt(Socket::IPPROTO_TCP, 3, $options[:tcpkeepalive_idle])
607+ $server.setsockopt(Socket::IPPROTO_TCP, 17, $options[:tcpkeepalive_intvl])
608+ $server.setsockopt(Socket::IPPROTO_TCP, 16, $options[:tcpkeepalive_cnt])
609+ elsif RUBY_PLATFORM.downcase =~ /darwin/
610+ # macOS 10.12.6 (Sierra) /usr/include/netinet/tcp.h
611+ $server.setsockopt(Socket::IPPROTO_TCP, 0x10, $options[:tcpkeepalive_idle])
612+ $server.setsockopt(Socket::IPPROTO_TCP, 0x101, $options[:tcpkeepalive_intvl])
613+ $server.setsockopt(Socket::IPPROTO_TCP, 0x102, $options[:tcpkeepalive_cnt])
614+ end
615+ end
570616 rescue
571617 log_error "Failed to connect to the server"
572618 $server = nil
@@ -611,7 +657,7 @@ end
611657 #
612658 def main_loop
613659 while true
614- ret, = select([$server, $engine], nil, nil, 60)
660+ ret, = select([$engine, $server], nil, nil, 60)
615661 unless ret
616662 # Send keep-alive
617663 if $bridge_state.too_quiet?
@@ -621,12 +667,14 @@ def main_loop
621667 next
622668 end
623669
624- ret.each do |io|
625- case io
626- when $engine
627- $bridge_state.do_engine_recv
628- when $server
629- $bridge_state.do_sever_recv
670+ ret.each_with_index do |io, idx|
671+ if (!$options[:ignoremultiselect] || idx == 0)
672+ case io
673+ when $engine
674+ $bridge_state.do_engine_recv
675+ when $server
676+ $bridge_state.do_sever_recv
677+ end
630678 end
631679 end
632680
--- a/shogi-server
+++ b/shogi-server
@@ -228,7 +228,10 @@ def parse_command_line
228228 ["--max-identifier", GetoptLong::REQUIRED_ARGUMENT],
229229 ["--max-moves", GetoptLong::REQUIRED_ARGUMENT],
230230 ["--pid-file", GetoptLong::REQUIRED_ARGUMENT],
231- ["--player-log-dir", GetoptLong::REQUIRED_ARGUMENT])
231+ ["--player-log-dir", GetoptLong::REQUIRED_ARGUMENT],
232+ ["--tcpkeepalive-idle", GetoptLong::REQUIRED_ARGUMENT],
233+ ["--tcpkeepalive-intvl", GetoptLong::REQUIRED_ARGUMENT],
234+ ["--tcpkeepalive-cnt", GetoptLong::REQUIRED_ARGUMENT])
232235 parser.quiet = true
233236 begin
234237 parser.each_option do |name, arg|
@@ -308,6 +311,15 @@ def check_command_line
308311
309312 $options["least-time-per-move"] ||= ShogiServer::Default_Least_Time_Per_Move
310313 $options["least-time-per-move"] = $options["least-time-per-move"].to_i
314+
315+ $options["tcpkeepalive-idle"] ||= ShogiServer::Default_TcpKeepAlive_Idle
316+ $options["tcpkeepalive-idle"] = $options["tcpkeepalive-idle"].to_i
317+
318+ $options["tcpkeepalive-intvl"] ||= ShogiServer::Default_TcpKeepAlive_Intvl
319+ $options["tcpkeepalive-intvl"] = $options["tcpkeepalive-intvl"].to_i
320+
321+ $options["tcpkeepalive-cnt"] ||= ShogiServer::Default_TcpKeepAlive_Cnt
322+ $options["tcpkeepalive-cnt"] = $options["tcpkeepalive-cnt"].to_i
311323 end
312324
313325 # See if a file can be created in the directory.
@@ -489,8 +501,30 @@ def main
489501 server.start do |client|
490502 begin
491503 # client.sync = true # this is already set in WEBrick
492- client.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true)
493- # Keepalive time can be set by /proc/sys/net/ipv4/tcp_keepalive_time
504+ if Socket.const_defined?(:SOL_SOCKET) &&
505+ Socket.const_defined?(:SO_KEEPALIVE) &&
506+ Socket.const_defined?(:IPPROTO_TCP)
507+ client.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, true)
508+ # Keepalive time can be set by /proc/sys/net/ipv4/tcp_keepalive_time
509+ if Socket.const_defined?(:TCP_KEEPIDLE) &&
510+ Socket.const_defined?(:TCP_KEEPINTVL) &&
511+ Socket.const_defined?(:TCP_KEEPCNT)
512+ client.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_KEEPIDLE, $options["tcpkeepalive-idle"])
513+ client.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_KEEPINTVL, $options["tcpkeepalive-intvl"])
514+ client.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_KEEPCNT, $options["tcpkeepalive-cnt"])
515+ elsif RUBY_PLATFORM.downcase =~ /mswin|mingw|cygwin|bccwin/
516+ # Windows 10 (1709 or later) ws2ipdef.h
517+ # https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-tcp-socket-options
518+ client.setsockopt(Socket::IPPROTO_TCP, 3, $options["tcpkeepalive-idle"])
519+ client.setsockopt(Socket::IPPROTO_TCP, 17, $options["tcpkeepalive-intvl"])
520+ client.setsockopt(Socket::IPPROTO_TCP, 16, $options["tcpkeepalive-cnt"])
521+ elsif RUBY_PLATFORM.downcase =~ /darwin/
522+ # macOS 10.12.6 (Sierra) /usr/include/netinet/tcp.h
523+ client.setsockopt(Socket::IPPROTO_TCP, 0x10, $options["tcpkeepalive-idle"])
524+ client.setsockopt(Socket::IPPROTO_TCP, 0x101, $options["tcpkeepalive-intvl"])
525+ client.setsockopt(Socket::IPPROTO_TCP, 0x102, $options["tcpkeepalive-cnt"])
526+ end
527+ end
494528 player, login = login_loop(client) # loop
495529 unless player
496530 log_error("Detected a timed out login attempt")
--- a/shogi_server.rb
+++ b/shogi_server.rb
@@ -51,6 +51,9 @@ Default_Timeout = 60 # for single socket operation
5151 Default_Game_Name = "default-1500-0"
5252 Default_Max_Moves = 256
5353 Default_Least_Time_Per_Move = 0
54+Default_TcpKeepAlive_Idle = 50
55+Default_TcpKeepAlive_Intvl = 5
56+Default_TcpKeepAlive_Cnt = 9
5457 One_Time = 10
5558 Login_Time = 300 # time for LOGIN
5659 Revision = "20180825"