Diff

net/server_select.lua @ 7099:8e64e7b82928

Merge 0.10->trunk
author Kim Alvefur <zash@zash.se>
date Fri, 22 Jan 2016 15:03:02 +0100
parent 7074:3ff83773ffc0
parent 7098:5286e79c6829
child 7324:7e6409462f79
line wrap: on
line diff
--- a/net/server_select.lua	Fri Jan 22 13:22:50 2016 +0000
+++ b/net/server_select.lua	Fri Jan 22 15:03:02 2016 +0100
@@ -87,6 +87,7 @@
 local _closelist
 local _readtimes
 local _writetimes
+local _fullservers
 
 --// simple data types //--
 
@@ -100,6 +101,7 @@
 
 local _selecttimeout
 local _tcpbacklog
+local _accepretry
 
 local _starttime
 local _currenttime
@@ -126,6 +128,7 @@
 _readtimes = { } -- key = handler, value = timestamp of last data reading
 _writetimes = { } -- key = handler, value = timestamp of last data writing/sending
 _closelist = { } -- handlers to close
+_fullservers = { } -- servers in a paused state while there are too many clients
 
 _readlistlen = 0 -- length of readlist
 _sendlistlen = 0 -- length of sendlist
@@ -136,6 +139,7 @@
 
 _selecttimeout = 1 -- timeout of socket.select
 _tcpbacklog = 128 -- some kind of hint to the OS
+_accepretry = 10 -- seconds to wait until the next attempt of a full server to accept
 
 _maxsendlen = 51000 * 1024 -- max len of send buffer
 _maxreadlen = 25000 * 1024 -- max len of read buffer
@@ -204,6 +208,7 @@
 				socket = nil;
 			end
 			handler.paused = true;
+			out_put("server.lua: server [", ip, "]:", serverport, " paused")
 		end
 	end
 	handler.resume = function( )
@@ -214,7 +219,9 @@
 			end
 			_readlistlen = addsocket(_readlist, socket, _readlistlen)
 			_socketlist[ socket ] = handler
+			_fullservers[ handler ] = nil
 			handler.paused = false;
+			out_put("server.lua: server [", ip, "]:", serverport, " resumed")
 		end
 	end
 	handler.ip = function( )
@@ -229,6 +236,7 @@
 	handler.readbuffer = function( )
 		if _readlistlen >= _maxselectlen or _sendlistlen >= _maxselectlen then
 			handler.pause( )
+			_fullservers[ handler ] = _currenttime
 			out_put( "server.lua: refused new client connection: server full" )
 			return false
 		end
@@ -247,6 +255,8 @@
 			return;
 		elseif err then -- maybe timeout or something else
 			out_put( "server.lua: error with new client connection: ", tostring(err) )
+			handler.pause( )
+			_fullservers[ handler ] = _currenttime
 			return false
 		end
 	end
@@ -259,6 +269,7 @@
 		out_error("server.lua: Disallowed FD number: "..socket:getfd()) -- PROTIP: Switch to libevent
 		socket:close( ) -- Should we send some kind of error here?
 		if server then
+			_fullservers[ server ] = _currenttime
 			server.pause( )
 		end
 		return nil, nil, "fd-too-large"
@@ -796,6 +807,7 @@
 		max_connections = _maxselectlen;
 		max_ssl_handshake_roundtrips = _maxsslhandshake;
 		highest_allowed_fd = _maxfd;
+		accept_retry_interval = _accepretry;
 	}
 end
 
@@ -810,6 +822,7 @@
 	_tcpbacklog = tonumber( new.tcp_backlog ) or _tcpbacklog
 	_sendtimeout = tonumber( new.send_timeout ) or _sendtimeout
 	_readtimeout = tonumber( new.read_timeout ) or _readtimeout
+	_accepretry = tonumber( new.accept_retry_interval ) or _accepretry
 	_maxselectlen = new.max_connections or _maxselectlen
 	_maxsslhandshake = new.max_ssl_handshake_roundtrips or _maxsslhandshake
 	_maxfd = new.highest_allowed_fd or _maxfd
@@ -884,7 +897,7 @@
 	_currenttime = luasocket_gettime( )
 	repeat
 		-- Fire timers
-		local next_timer_time = math_huge;
+	local next_timer_time = math_huge;
 		for i = 1, _timerlistlen do
 			local t = _timerlist[ i ]( _currenttime ) -- fire timers
 			if t then next_timer_time = math_min(next_timer_time, t); end
@@ -936,6 +949,13 @@
 				end
 			end
 		end
+
+		for server, paused_time in pairs( _fullservers ) do
+			if _currenttime - paused_time > _accepretry then
+				_fullservers[ server ] = nil;
+				server.resume();
+			end
+		end
 	until quitting;
 	if once and quitting == "once" then quitting = nil; return; end
 	closeall();