Software / code / prosody
Comparison
net/server_select.lua @ 5331:ffa740b4f08d
net.server_select: Limit global number of sockets passed to select.
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Tue, 12 Feb 2013 03:24:41 +0100 |
| parent | 5330:0a0ca2eb991b |
| child | 5337:c22dd451487f |
comparison
equal
deleted
inserted
replaced
| 5330:0a0ca2eb991b | 5331:ffa740b4f08d |
|---|---|
| 120 | 120 |
| 121 local _cleanqueue | 121 local _cleanqueue |
| 122 | 122 |
| 123 local _timer | 123 local _timer |
| 124 | 124 |
| 125 local _maxclientsperserver | 125 local _maxselectlen |
| 126 local _maxfd | |
| 126 | 127 |
| 127 local _maxsslhandshake | 128 local _maxsslhandshake |
| 128 | 129 |
| 129 ----------------------------------// DEFINITION //-- | 130 ----------------------------------// DEFINITION //-- |
| 130 | 131 |
| 154 _sendtimeout = 60000 -- allowed send idle time in secs | 155 _sendtimeout = 60000 -- allowed send idle time in secs |
| 155 _readtimeout = 6 * 60 * 60 -- allowed read idle time in secs | 156 _readtimeout = 6 * 60 * 60 -- allowed read idle time in secs |
| 156 | 157 |
| 157 _cleanqueue = false -- clean bufferqueue after using | 158 _cleanqueue = false -- clean bufferqueue after using |
| 158 | 159 |
| 159 _maxclientsperserver = 1000 | 160 _maxfd = luasocket._SETSIZE or 1024 -- We should ignore this on Windows. Perhaps by simply setting it to math.huge or something. |
| 161 _maxselectlen = luasocket._SETSIZE or 1024 -- But this still applies on Windows | |
| 160 | 162 |
| 161 _maxsslhandshake = 30 -- max handshake round-trips | 163 _maxsslhandshake = 30 -- max handshake round-trips |
| 162 | 164 |
| 163 ----------------------------------// PRIVATE //-- | 165 ----------------------------------// PRIVATE //-- |
| 164 | 166 |
| 165 wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx, maxconnections ) -- this function wraps a server | 167 wrapserver = function( listeners, socket, ip, serverport, pattern, sslctx ) -- this function wraps a server -- FIXME Make sure FD < _maxfd |
| 166 | 168 |
| 167 maxconnections = maxconnections or _maxclientsperserver | 169 if socket:getfd() >= _maxfd then |
| 170 out_error("server.lua: Disallowed FD number: "..socket:getfd()) | |
| 171 socket:close() | |
| 172 return nil, "fd-too-large" | |
| 173 end | |
| 168 | 174 |
| 169 local connections = 0 | 175 local connections = 0 |
| 170 | 176 |
| 171 local dispatch, disconnect = listeners.onconnect, listeners.ondisconnect | 177 local dispatch, disconnect = listeners.onconnect, listeners.ondisconnect |
| 172 | 178 |
| 231 end | 237 end |
| 232 handler.socket = function( ) | 238 handler.socket = function( ) |
| 233 return socket | 239 return socket |
| 234 end | 240 end |
| 235 handler.readbuffer = function( ) | 241 handler.readbuffer = function( ) |
| 236 if connections > maxconnections then | 242 if _readlistlen >= _maxselectlen or _sendlistlen >= _maxselectlen then |
| 237 handler.pause( ) | 243 handler.pause( ) |
| 238 out_put( "server.lua: refused new client connection: server full" ) | 244 out_put( "server.lua: refused new client connection: server full" ) |
| 239 return false | 245 return false |
| 240 end | 246 end |
| 241 local client, err = accept( socket ) -- try to accept | 247 local client, err = accept( socket ) -- try to accept |
| 259 return handler | 265 return handler |
| 260 end | 266 end |
| 261 | 267 |
| 262 wrapconnection = function( server, listeners, socket, ip, serverport, clientport, pattern, sslctx ) -- this function wraps a client to a handler object | 268 wrapconnection = function( server, listeners, socket, ip, serverport, clientport, pattern, sslctx ) -- this function wraps a client to a handler object |
| 263 | 269 |
| 270 if socket:getfd() >= _maxfd then | |
| 271 out_error("server.lua: Disallowed FD number: "..socket:getfd()) -- PROTIP: Switch to libevent | |
| 272 socket:close( ) -- Should we send some kind of error here? | |
| 273 server.pause( ) | |
| 274 return nil, nil, "fd-too-large" | |
| 275 end | |
| 264 socket:settimeout( 0 ) | 276 socket:settimeout( 0 ) |
| 265 | 277 |
| 266 --// local import of socket methods //-- | 278 --// local import of socket methods //-- |
| 267 | 279 |
| 268 local send | 280 local send |
| 722 local server, err = socket_bind( addr, port ) | 734 local server, err = socket_bind( addr, port ) |
| 723 if err then | 735 if err then |
| 724 out_error( "server.lua, [", addr, "]:", port, ": ", err ) | 736 out_error( "server.lua, [", addr, "]:", port, ": ", err ) |
| 725 return nil, err | 737 return nil, err |
| 726 end | 738 end |
| 727 local handler, err = wrapserver( listeners, server, addr, port, pattern, sslctx, _maxclientsperserver ) -- wrap new server socket | 739 local handler, err = wrapserver( listeners, server, addr, port, pattern, sslctx ) -- wrap new server socket |
| 728 if not handler then | 740 if not handler then |
| 729 server:close( ) | 741 server:close( ) |
| 730 return nil, err | 742 return nil, err |
| 731 end | 743 end |
| 732 server:settimeout( 0 ) | 744 server:settimeout( 0 ) |
| 766 _socketlist = { } | 778 _socketlist = { } |
| 767 --mem_free( ) | 779 --mem_free( ) |
| 768 end | 780 end |
| 769 | 781 |
| 770 getsettings = function( ) | 782 getsettings = function( ) |
| 771 return _selecttimeout, _sleeptime, _maxsendlen, _maxreadlen, _checkinterval, _sendtimeout, _readtimeout, _cleanqueue, _maxclientsperserver, _maxsslhandshake | 783 return _selecttimeout, _sleeptime, _maxsendlen, _maxreadlen, _checkinterval, _sendtimeout, _readtimeout, _cleanqueue, _maxselectlen, _maxsslhandshake, _maxfd |
| 772 end | 784 end |
| 773 | 785 |
| 774 changesettings = function( new ) | 786 changesettings = function( new ) |
| 775 if type( new ) ~= "table" then | 787 if type( new ) ~= "table" then |
| 776 return nil, "invalid settings table" | 788 return nil, "invalid settings table" |
| 781 _maxreadlen = tonumber( new.max_receive_buffer_size ) or _maxreadlen | 793 _maxreadlen = tonumber( new.max_receive_buffer_size ) or _maxreadlen |
| 782 _checkinterval = tonumber( new.select_idle_check_interval ) or _checkinterval | 794 _checkinterval = tonumber( new.select_idle_check_interval ) or _checkinterval |
| 783 _sendtimeout = tonumber( new.send_timeout ) or _sendtimeout | 795 _sendtimeout = tonumber( new.send_timeout ) or _sendtimeout |
| 784 _readtimeout = tonumber( new.read_timeout ) or _readtimeout | 796 _readtimeout = tonumber( new.read_timeout ) or _readtimeout |
| 785 _cleanqueue = new.select_clean_queue | 797 _cleanqueue = new.select_clean_queue |
| 786 _maxclientsperserver = new.max_connections or _maxclientsperserver | 798 _maxselectlen = new.max_connections or _maxselectlen |
| 787 _maxsslhandshake = new.max_ssl_handshake_roundtrips or _maxsslhandshake | 799 _maxsslhandshake = new.max_ssl_handshake_roundtrips or _maxsslhandshake |
| 800 _maxfd = new.highest_allowed_fd or _maxfd | |
| 788 return true | 801 return true |
| 789 end | 802 end |
| 790 | 803 |
| 791 addtimer = function( listener ) | 804 addtimer = function( listener ) |
| 792 if type( listener ) ~= "function" then | 805 if type( listener ) ~= "function" then |
| 863 end | 876 end |
| 864 | 877 |
| 865 --// EXPERIMENTAL //-- | 878 --// EXPERIMENTAL //-- |
| 866 | 879 |
| 867 local wrapclient = function( socket, ip, serverport, listeners, pattern, sslctx ) | 880 local wrapclient = function( socket, ip, serverport, listeners, pattern, sslctx ) |
| 868 local handler = wrapconnection( nil, listeners, socket, ip, serverport, "clientport", pattern, sslctx ) | 881 local handler, socket, err = wrapconnection( nil, listeners, socket, ip, serverport, "clientport", pattern, sslctx ) |
| 882 if not handler then return nil, err end | |
| 869 _socketlist[ socket ] = handler | 883 _socketlist[ socket ] = handler |
| 870 if not sslctx then | 884 if not sslctx then |
| 871 _sendlistlen = addsocket(_sendlist, socket, _sendlistlen) | 885 _sendlistlen = addsocket(_sendlist, socket, _sendlistlen) |
| 872 if listeners.onconnect then | 886 if listeners.onconnect then |
| 873 -- When socket is writeable, call onconnect | 887 -- When socket is writeable, call onconnect |