Fixed setting of socket.timeout in httpd (was not currently set before).
Adopted the nanoseconds timeout precision - in config file added support for ns, us, ms, s timeout precision (without indication, it uses `seconds` precision).
This commit is contained in:
@@ -12,10 +12,10 @@ note
|
||||
max_concurrent_connections: set to 1, for single threaded behavior
|
||||
max_tcp_clients: max number of open tcp connection
|
||||
|
||||
socket_timeout: connection timeout
|
||||
socket_recv_timeout: read data timeout
|
||||
socket_timeout_ns: connection timeout in nanoseconds
|
||||
socket_recv_timeout_ns: read data timeout in nanoseconds
|
||||
|
||||
keep_alive_timeout: amount of time the server will wait for subsequent
|
||||
keep_alive_timeout_ns: amount of nanoseconds the server will wait for subsequent
|
||||
requests on a persistent connection,
|
||||
max_keep_alive_requests: number of requests allowed on a persistent connection,
|
||||
|
||||
@@ -40,6 +40,8 @@ inherit
|
||||
|
||||
WGI_STANDALONE_HTTPD_LOGGER_CONSTANTS
|
||||
|
||||
WSF_TIMEOUT_UTILITIES
|
||||
|
||||
create
|
||||
make,
|
||||
make_and_launch
|
||||
@@ -57,9 +59,9 @@ feature {NONE} -- Initialization
|
||||
port_number := {WGI_STANDALONE_CONSTANTS}.default_http_server_port --| Default, but quite often, this port is already used ...
|
||||
max_concurrent_connections := {WGI_STANDALONE_CONSTANTS}.default_max_concurrent_connections
|
||||
max_tcp_clients := {WGI_STANDALONE_CONSTANTS}.default_max_tcp_clients
|
||||
socket_timeout := {WGI_STANDALONE_CONSTANTS}.default_socket_timeout -- seconds
|
||||
socket_recv_timeout := {WGI_STANDALONE_CONSTANTS}.default_socket_recv_timeout -- seconds
|
||||
keep_alive_timeout := {WGI_STANDALONE_CONSTANTS}.default_keep_alive_timeout -- seconds.
|
||||
socket_timeout_ns := seconds_to_nanoseconds ({WGI_STANDALONE_CONSTANTS}.default_socket_timeout) -- default in seconds
|
||||
socket_recv_timeout_ns := seconds_to_nanoseconds ({WGI_STANDALONE_CONSTANTS}.default_socket_recv_timeout) -- default in seconds
|
||||
keep_alive_timeout_ns := seconds_to_nanoseconds ({WGI_STANDALONE_CONSTANTS}.default_keep_alive_timeout) -- default in seconds.
|
||||
max_keep_alive_requests := {WGI_STANDALONE_CONSTANTS}.default_max_keep_alive_requests
|
||||
verbose := False
|
||||
verbose_level := notice_level
|
||||
@@ -111,9 +113,9 @@ feature {NONE} -- Initialization
|
||||
end
|
||||
max_concurrent_connections := opts.option_integer_value ("max_concurrent_connections", max_concurrent_connections)
|
||||
max_tcp_clients := opts.option_integer_value ("max_tcp_clients", max_tcp_clients)
|
||||
socket_timeout := opts.option_integer_value ("socket_timeout", socket_timeout)
|
||||
socket_recv_timeout := opts.option_integer_value ("socket_recv_timeout", socket_recv_timeout)
|
||||
keep_alive_timeout := opts.option_integer_value ("keep_alive_timeout", keep_alive_timeout)
|
||||
socket_timeout_ns := opts.option_timeout_ns_value ("socket_timeout", socket_timeout_ns)
|
||||
socket_recv_timeout_ns := opts.option_timeout_ns_value ("socket_recv_timeout", socket_recv_timeout_ns)
|
||||
keep_alive_timeout_ns := opts.option_timeout_ns_value ("keep_alive_timeout", keep_alive_timeout_ns)
|
||||
max_keep_alive_requests := opts.option_integer_value ("max_keep_alive_requests", max_keep_alive_requests)
|
||||
|
||||
if
|
||||
@@ -169,9 +171,9 @@ feature -- Execution
|
||||
cfg.http_server_port := port_number
|
||||
cfg.set_max_concurrent_connections (max_concurrent_connections)
|
||||
cfg.set_max_tcp_clients (max_tcp_clients)
|
||||
cfg.set_socket_timeout (socket_timeout)
|
||||
cfg.set_socket_recv_timeout (socket_recv_timeout)
|
||||
cfg.set_keep_alive_timeout (keep_alive_timeout)
|
||||
cfg.set_socket_timeout_ns (socket_timeout_ns)
|
||||
cfg.set_socket_recv_timeout_ns (socket_recv_timeout_ns)
|
||||
cfg.set_keep_alive_timeout_ns (keep_alive_timeout_ns)
|
||||
cfg.set_max_keep_alive_requests (max_keep_alive_requests)
|
||||
end
|
||||
|
||||
@@ -244,10 +246,10 @@ feature {NONE} -- Implementation
|
||||
end
|
||||
|
||||
max_tcp_clients: INTEGER
|
||||
socket_timeout: INTEGER
|
||||
socket_recv_timeout: INTEGER
|
||||
socket_timeout_ns: NATURAL_64
|
||||
socket_recv_timeout_ns: NATURAL_64
|
||||
|
||||
keep_alive_timeout: INTEGER
|
||||
keep_alive_timeout_ns: NATURAL_64
|
||||
max_keep_alive_requests: INTEGER
|
||||
|
||||
is_secure_connection_supported: BOOLEAN
|
||||
|
||||
@@ -23,6 +23,8 @@ deferred class
|
||||
inherit
|
||||
WEB_SOCKET_CONSTANTS
|
||||
|
||||
WSF_TIMEOUT_UTILITIES
|
||||
|
||||
REFACTORING_HELPER
|
||||
|
||||
feature -- Web Socket Interface
|
||||
@@ -90,13 +92,18 @@ feature -- Websocket events
|
||||
|
||||
feature {WEB_SOCKET} -- Timeout.
|
||||
|
||||
timer_delay: INTEGER
|
||||
-- Maximal duration in seconds between two `on_timeout` event.
|
||||
timer_delay_ns: NATURAL_64
|
||||
-- Maximal duration in nanoseconds between two `on_timeout` event.
|
||||
-- Disable timeout event, by setting it to `0` (default).
|
||||
|
||||
set_timer_delay_ns (nb_nanosecs: NATURAL_64)
|
||||
do
|
||||
timer_delay_ns := nb_nanosecs
|
||||
end
|
||||
|
||||
set_timer_delay (nb_secs: INTEGER)
|
||||
do
|
||||
timer_delay := nb_secs
|
||||
timer_delay_ns := seconds_to_nanoseconds (nb_secs)
|
||||
end
|
||||
|
||||
on_timer (ws: WEB_SOCKET)
|
||||
@@ -143,7 +150,7 @@ feature -- Websocket events: implemented
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
copyright: "2011-2018, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -42,7 +42,7 @@ feature {NONE} -- Initialization
|
||||
end
|
||||
end
|
||||
|
||||
feature {NONE} -- Access
|
||||
feature {WEB_SOCKET_EVENT_I} -- Access
|
||||
|
||||
request: WSF_REQUEST
|
||||
-- Associated request.
|
||||
@@ -209,29 +209,30 @@ feature {WEB_SOCKET_HANDLER} -- Networking
|
||||
|
||||
wait_for_input (cb: detachable WEB_SOCKET_EVENT_I)
|
||||
local
|
||||
l_timeout, nb: INTEGER
|
||||
l_cb_timeout: INTEGER
|
||||
nb,
|
||||
l_timeout_ns,
|
||||
l_cb_timeout_ns: NATURAL_64
|
||||
do
|
||||
has_input := False
|
||||
if cb = Void then
|
||||
has_input := socket.ready_for_reading
|
||||
else
|
||||
l_cb_timeout := cb.timer_delay
|
||||
l_timeout := socket.timeout
|
||||
if l_cb_timeout = 0 then
|
||||
l_cb_timeout_ns := cb.timer_delay_ns
|
||||
l_timeout_ns := socket.timeout_ns
|
||||
if l_cb_timeout_ns = 0 then
|
||||
-- timeout event not enabled.
|
||||
has_input := socket.ready_for_reading
|
||||
else
|
||||
cb.on_timer (Current)
|
||||
if l_cb_timeout > l_timeout then
|
||||
if l_cb_timeout_ns > l_timeout_ns then
|
||||
-- event timeout duration is bigger than socket timeout
|
||||
-- thus, no on_timeout before next frame waiting
|
||||
has_input := socket.ready_for_reading
|
||||
else
|
||||
from
|
||||
l_timeout := socket.timeout
|
||||
nb := l_timeout
|
||||
socket.set_timeout (l_cb_timeout) -- FIXME: for now 1 sec is the smaller timeout we can use.
|
||||
l_timeout_ns := socket.timeout_ns
|
||||
nb := l_timeout_ns
|
||||
socket.set_timeout_ns (l_cb_timeout_ns)
|
||||
until
|
||||
has_input or nb <= 0
|
||||
loop
|
||||
@@ -239,13 +240,13 @@ feature {WEB_SOCKET_HANDLER} -- Networking
|
||||
if not has_input then
|
||||
-- Call on_timeout only if there is no input,
|
||||
-- otherwise it was called once before the initial wait.
|
||||
socket.set_timeout (l_timeout)
|
||||
socket.set_timeout_ns (l_timeout_ns)
|
||||
cb.on_timer (Current)
|
||||
socket.set_timeout (l_cb_timeout)
|
||||
socket.set_timeout_ns (l_cb_timeout_ns)
|
||||
end
|
||||
nb := nb - l_cb_timeout
|
||||
nb := nb - l_cb_timeout_ns
|
||||
end
|
||||
socket.set_timeout (l_timeout)
|
||||
socket.set_timeout_ns (l_timeout_ns)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -772,7 +773,7 @@ feature {NONE} -- Debug
|
||||
end
|
||||
|
||||
note
|
||||
copyright: "2011-2017, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
copyright: "2011-2018, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
|
||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||
source: "[
|
||||
Eiffel Software
|
||||
|
||||
@@ -152,6 +152,80 @@ feature -- Helpers
|
||||
end
|
||||
end
|
||||
|
||||
option_natural_64_value (a_opt_name: READABLE_STRING_GENERAL; a_default: NATURAL_64): NATURAL_64
|
||||
-- NATURAL_64 value associated to option name `a_opt_name', other return `a_default'.
|
||||
local
|
||||
s: READABLE_STRING_GENERAL
|
||||
do
|
||||
Result := a_default
|
||||
if attached option (a_opt_name) as opt then
|
||||
if attached {NATURAL_64} opt as n then
|
||||
Result := n
|
||||
else
|
||||
s := opt.out
|
||||
if s.is_natural_64 then
|
||||
Result := s.to_natural_64
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
option_timeout_ns_value (a_opt_name: READABLE_STRING_GENERAL; a_default: NATURAL_64): NATURAL_64
|
||||
-- Timeout in nanoseconds associated to option name `a_opt_name', other return `a_default'.
|
||||
local
|
||||
v: detachable READABLE_STRING_GENERAL
|
||||
s: STRING_32
|
||||
i,l_count: INTEGER
|
||||
do
|
||||
if a_opt_name.ends_with ("_ns") then
|
||||
-- Option use "nanoseconds" convention.
|
||||
Result := option_natural_64_value (a_opt_name, a_default)
|
||||
elseif attached option (a_opt_name) as opt then
|
||||
if attached {READABLE_STRING_GENERAL} opt as str then
|
||||
from
|
||||
i := 1
|
||||
l_count := str.count
|
||||
until
|
||||
i > l_count or v /= Void
|
||||
loop
|
||||
if str[i].is_space then
|
||||
-- ignore
|
||||
elseif str[i].is_digit then
|
||||
-- Keep it
|
||||
else
|
||||
v := str.head (i - 1)
|
||||
create s.make_from_string_general (str.substring (i, l_count))
|
||||
s.adjust
|
||||
end
|
||||
i := i + 1
|
||||
end
|
||||
if v = Void then
|
||||
v := str
|
||||
end
|
||||
if v /= Void then
|
||||
if s = Void or else s.is_whitespace or else s.is_case_insensitive_equal_general ("s") then
|
||||
-- Consider as `seconds` for backward compatibility
|
||||
Result := timeout_utilities.seconds_to_nanoseconds (v.to_integer)
|
||||
elseif s.is_case_insensitive_equal_general ("ns") then
|
||||
check v.is_natural_64 end
|
||||
Result := v.to_natural_64
|
||||
elseif s.is_case_insensitive_equal_general ("us") then
|
||||
check v.is_integer end
|
||||
Result := timeout_utilities.microseconds_to_nanoseconds (v.to_integer)
|
||||
elseif s.is_case_insensitive_equal_general ("ms") then
|
||||
check v.is_integer end
|
||||
Result := timeout_utilities.milliseconds_to_nanoseconds (v.to_integer)
|
||||
end
|
||||
else
|
||||
-- Error!
|
||||
end
|
||||
else
|
||||
-- Backward comptability with timeout in seconds!
|
||||
Result := timeout_utilities.seconds_to_nanoseconds (option_integer_value (a_opt_name, timeout_utilities.nanoseconds_to_seconds (a_default)))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
option_boolean_value (a_opt_name: READABLE_STRING_GENERAL; a_default: BOOLEAN): BOOLEAN
|
||||
-- BOOLEAN value associated to option name `a_opt_name', other return `a_default'.
|
||||
local
|
||||
@@ -222,6 +296,11 @@ feature {NONE} -- Implementation
|
||||
options: STRING_TABLE [detachable ANY]
|
||||
-- Custom options which might be support (or not) by the default service
|
||||
|
||||
timeout_utilities: WSF_TIMEOUT_UTILITIES
|
||||
once
|
||||
create Result
|
||||
end
|
||||
|
||||
invariant
|
||||
options_attached: options /= Void
|
||||
note
|
||||
|
||||
Reference in New Issue
Block a user