Software /
code /
prosody
Comparison
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 |
comparison
equal
deleted
inserted
replaced
7091:1c3b38f80571 | 7099:8e64e7b82928 |
---|---|
85 local _sendlist | 85 local _sendlist |
86 local _socketlist | 86 local _socketlist |
87 local _closelist | 87 local _closelist |
88 local _readtimes | 88 local _readtimes |
89 local _writetimes | 89 local _writetimes |
90 local _fullservers | |
90 | 91 |
91 --// simple data types //-- | 92 --// simple data types //-- |
92 | 93 |
93 local _ | 94 local _ |
94 local _readlistlen | 95 local _readlistlen |
98 local _sendtraffic | 99 local _sendtraffic |
99 local _readtraffic | 100 local _readtraffic |
100 | 101 |
101 local _selecttimeout | 102 local _selecttimeout |
102 local _tcpbacklog | 103 local _tcpbacklog |
104 local _accepretry | |
103 | 105 |
104 local _starttime | 106 local _starttime |
105 local _currenttime | 107 local _currenttime |
106 | 108 |
107 local _maxsendlen | 109 local _maxsendlen |
124 _timerlist = { } -- array of timer functions | 126 _timerlist = { } -- array of timer functions |
125 _socketlist = { } -- key = socket, value = wrapped socket (handlers) | 127 _socketlist = { } -- key = socket, value = wrapped socket (handlers) |
126 _readtimes = { } -- key = handler, value = timestamp of last data reading | 128 _readtimes = { } -- key = handler, value = timestamp of last data reading |
127 _writetimes = { } -- key = handler, value = timestamp of last data writing/sending | 129 _writetimes = { } -- key = handler, value = timestamp of last data writing/sending |
128 _closelist = { } -- handlers to close | 130 _closelist = { } -- handlers to close |
131 _fullservers = { } -- servers in a paused state while there are too many clients | |
129 | 132 |
130 _readlistlen = 0 -- length of readlist | 133 _readlistlen = 0 -- length of readlist |
131 _sendlistlen = 0 -- length of sendlist | 134 _sendlistlen = 0 -- length of sendlist |
132 _timerlistlen = 0 -- lenght of timerlist | 135 _timerlistlen = 0 -- lenght of timerlist |
133 | 136 |
134 _sendtraffic = 0 -- some stats | 137 _sendtraffic = 0 -- some stats |
135 _readtraffic = 0 | 138 _readtraffic = 0 |
136 | 139 |
137 _selecttimeout = 1 -- timeout of socket.select | 140 _selecttimeout = 1 -- timeout of socket.select |
138 _tcpbacklog = 128 -- some kind of hint to the OS | 141 _tcpbacklog = 128 -- some kind of hint to the OS |
142 _accepretry = 10 -- seconds to wait until the next attempt of a full server to accept | |
139 | 143 |
140 _maxsendlen = 51000 * 1024 -- max len of send buffer | 144 _maxsendlen = 51000 * 1024 -- max len of send buffer |
141 _maxreadlen = 25000 * 1024 -- max len of read buffer | 145 _maxreadlen = 25000 * 1024 -- max len of read buffer |
142 | 146 |
143 _checkinterval = 30 -- interval in secs to check idle clients | 147 _checkinterval = 30 -- interval in secs to check idle clients |
202 _socketlist[ socket ] = nil | 206 _socketlist[ socket ] = nil |
203 socket:close( ) | 207 socket:close( ) |
204 socket = nil; | 208 socket = nil; |
205 end | 209 end |
206 handler.paused = true; | 210 handler.paused = true; |
211 out_put("server.lua: server [", ip, "]:", serverport, " paused") | |
207 end | 212 end |
208 end | 213 end |
209 handler.resume = function( ) | 214 handler.resume = function( ) |
210 if handler.paused then | 215 if handler.paused then |
211 if not socket then | 216 if not socket then |
212 socket = socket_bind( ip, serverport, _tcpbacklog ); | 217 socket = socket_bind( ip, serverport, _tcpbacklog ); |
213 socket:settimeout( 0 ) | 218 socket:settimeout( 0 ) |
214 end | 219 end |
215 _readlistlen = addsocket(_readlist, socket, _readlistlen) | 220 _readlistlen = addsocket(_readlist, socket, _readlistlen) |
216 _socketlist[ socket ] = handler | 221 _socketlist[ socket ] = handler |
222 _fullservers[ handler ] = nil | |
217 handler.paused = false; | 223 handler.paused = false; |
224 out_put("server.lua: server [", ip, "]:", serverport, " resumed") | |
218 end | 225 end |
219 end | 226 end |
220 handler.ip = function( ) | 227 handler.ip = function( ) |
221 return ip | 228 return ip |
222 end | 229 end |
227 return socket | 234 return socket |
228 end | 235 end |
229 handler.readbuffer = function( ) | 236 handler.readbuffer = function( ) |
230 if _readlistlen >= _maxselectlen or _sendlistlen >= _maxselectlen then | 237 if _readlistlen >= _maxselectlen or _sendlistlen >= _maxselectlen then |
231 handler.pause( ) | 238 handler.pause( ) |
239 _fullservers[ handler ] = _currenttime | |
232 out_put( "server.lua: refused new client connection: server full" ) | 240 out_put( "server.lua: refused new client connection: server full" ) |
233 return false | 241 return false |
234 end | 242 end |
235 local client, err = accept( socket ) -- try to accept | 243 local client, err = accept( socket ) -- try to accept |
236 if client then | 244 if client then |
245 return dispatch( handler ); | 253 return dispatch( handler ); |
246 end | 254 end |
247 return; | 255 return; |
248 elseif err then -- maybe timeout or something else | 256 elseif err then -- maybe timeout or something else |
249 out_put( "server.lua: error with new client connection: ", tostring(err) ) | 257 out_put( "server.lua: error with new client connection: ", tostring(err) ) |
258 handler.pause( ) | |
259 _fullservers[ handler ] = _currenttime | |
250 return false | 260 return false |
251 end | 261 end |
252 end | 262 end |
253 return handler | 263 return handler |
254 end | 264 end |
257 | 267 |
258 if socket:getfd() >= _maxfd then | 268 if socket:getfd() >= _maxfd then |
259 out_error("server.lua: Disallowed FD number: "..socket:getfd()) -- PROTIP: Switch to libevent | 269 out_error("server.lua: Disallowed FD number: "..socket:getfd()) -- PROTIP: Switch to libevent |
260 socket:close( ) -- Should we send some kind of error here? | 270 socket:close( ) -- Should we send some kind of error here? |
261 if server then | 271 if server then |
272 _fullservers[ server ] = _currenttime | |
262 server.pause( ) | 273 server.pause( ) |
263 end | 274 end |
264 return nil, nil, "fd-too-large" | 275 return nil, nil, "fd-too-large" |
265 end | 276 end |
266 socket:settimeout( 0 ) | 277 socket:settimeout( 0 ) |
794 send_timeout = _sendtimeout; | 805 send_timeout = _sendtimeout; |
795 read_timeout = _readtimeout; | 806 read_timeout = _readtimeout; |
796 max_connections = _maxselectlen; | 807 max_connections = _maxselectlen; |
797 max_ssl_handshake_roundtrips = _maxsslhandshake; | 808 max_ssl_handshake_roundtrips = _maxsslhandshake; |
798 highest_allowed_fd = _maxfd; | 809 highest_allowed_fd = _maxfd; |
810 accept_retry_interval = _accepretry; | |
799 } | 811 } |
800 end | 812 end |
801 | 813 |
802 changesettings = function( new ) | 814 changesettings = function( new ) |
803 if type( new ) ~= "table" then | 815 if type( new ) ~= "table" then |
808 _maxreadlen = tonumber( new.max_receive_buffer_size ) or _maxreadlen | 820 _maxreadlen = tonumber( new.max_receive_buffer_size ) or _maxreadlen |
809 _checkinterval = tonumber( new.select_idle_check_interval ) or _checkinterval | 821 _checkinterval = tonumber( new.select_idle_check_interval ) or _checkinterval |
810 _tcpbacklog = tonumber( new.tcp_backlog ) or _tcpbacklog | 822 _tcpbacklog = tonumber( new.tcp_backlog ) or _tcpbacklog |
811 _sendtimeout = tonumber( new.send_timeout ) or _sendtimeout | 823 _sendtimeout = tonumber( new.send_timeout ) or _sendtimeout |
812 _readtimeout = tonumber( new.read_timeout ) or _readtimeout | 824 _readtimeout = tonumber( new.read_timeout ) or _readtimeout |
825 _accepretry = tonumber( new.accept_retry_interval ) or _accepretry | |
813 _maxselectlen = new.max_connections or _maxselectlen | 826 _maxselectlen = new.max_connections or _maxselectlen |
814 _maxsslhandshake = new.max_ssl_handshake_roundtrips or _maxsslhandshake | 827 _maxsslhandshake = new.max_ssl_handshake_roundtrips or _maxsslhandshake |
815 _maxfd = new.highest_allowed_fd or _maxfd | 828 _maxfd = new.highest_allowed_fd or _maxfd |
816 return true | 829 return true |
817 end | 830 end |
882 if quitting then return "quitting"; end | 895 if quitting then return "quitting"; end |
883 if once then quitting = "once"; end | 896 if once then quitting = "once"; end |
884 _currenttime = luasocket_gettime( ) | 897 _currenttime = luasocket_gettime( ) |
885 repeat | 898 repeat |
886 -- Fire timers | 899 -- Fire timers |
887 local next_timer_time = math_huge; | 900 local next_timer_time = math_huge; |
888 for i = 1, _timerlistlen do | 901 for i = 1, _timerlistlen do |
889 local t = _timerlist[ i ]( _currenttime ) -- fire timers | 902 local t = _timerlist[ i ]( _currenttime ) -- fire timers |
890 if t then next_timer_time = math_min(next_timer_time, t); end | 903 if t then next_timer_time = math_min(next_timer_time, t); end |
891 end | 904 end |
892 | 905 |
932 handler:close( ) -- forced disconnect? | 945 handler:close( ) -- forced disconnect? |
933 else | 946 else |
934 _readtimes[ handler ] = _currenttime -- reset timer | 947 _readtimes[ handler ] = _currenttime -- reset timer |
935 end | 948 end |
936 end | 949 end |
950 end | |
951 end | |
952 | |
953 for server, paused_time in pairs( _fullservers ) do | |
954 if _currenttime - paused_time > _accepretry then | |
955 _fullservers[ server ] = nil; | |
956 server.resume(); | |
937 end | 957 end |
938 end | 958 end |
939 until quitting; | 959 until quitting; |
940 if once and quitting == "once" then quitting = nil; return; end | 960 if once and quitting == "once" then quitting = nil; return; end |
941 closeall(); | 961 closeall(); |