diff --git a/examples/websocket/ws.ini b/examples/websocket/ws.ini index 87dcb630..606fa065 100644 --- a/examples/websocket/ws.ini +++ b/examples/websocket/ws.ini @@ -4,10 +4,10 @@ port=9090 max_concurrent_connections=100 max_tcp_clients=100 socket_timeout=30 -socket_recv_timeout=5 +socket_recv_timeout=100 ms #Persistent connections -keep_alive_timeout=2 +keep_alive_timeout=50 ms max_keep_alive_requests=-1 #SSL diff --git a/library/server/httpd/configuration/httpd_configuration_i.e b/library/server/httpd/configuration/httpd_configuration_i.e index b9e20b10..dc0750f0 100644 --- a/library/server/httpd/configuration/httpd_configuration_i.e +++ b/library/server/httpd/configuration/httpd_configuration_i.e @@ -11,6 +11,8 @@ inherit HTTPD_CONSTANTS + SOCKET_TIMEOUT_UTILITIES + feature {NONE} -- Initialization make @@ -18,9 +20,9 @@ feature {NONE} -- Initialization http_server_port := default_http_server_port max_concurrent_connections := default_max_concurrent_connections max_tcp_clients := default_max_tcp_clients - socket_timeout := default_socket_timeout - socket_recv_timeout := default_socket_recv_timeout - keep_alive_timeout := default_keep_alive_timeout + socket_timeout_ns := seconds_to_nanoseconds (default_socket_timeout) + socket_recv_timeout_ns := seconds_to_nanoseconds (default_socket_recv_timeout) + keep_alive_timeout_ns := seconds_to_nanoseconds (default_keep_alive_timeout) max_keep_alive_requests := default_max_keep_alive_requests is_secure := False create secure_certificate.make_empty @@ -39,12 +41,12 @@ feature -- Access max_tcp_clients: INTEGER assign set_max_tcp_clients -- Listen on socket for at most `queue' connections. - socket_timeout: INTEGER assign set_socket_timeout + socket_timeout_ns: NATURAL_64 assign set_socket_timeout_ns -- Amount of seconds that the server waits for receipts and transmissions during communications. -- note: with timeout of 0, socket can wait for ever. -- By default: 60 seconds, which is appropriate for most situations. - socket_recv_timeout: INTEGER assign set_socket_recv_timeout + socket_recv_timeout_ns: NATURAL_64 assign set_socket_recv_timeout_ns -- Amount of seconds that the server waits for receiving data during communications. -- note: with timeout of 0, socket can wait for ever. -- By default: 5 seconds. @@ -65,7 +67,7 @@ feature -- Access verbose_level: INTEGER assign set_verbose_level -- Verbosity of output. - keep_alive_timeout: INTEGER assign set_keep_alive_timeout + keep_alive_timeout_ns: NATURAL_64 assign set_keep_alive_timeout_ns -- Persistent connection timeout. -- Number of seconds the server waits after a request has been served before it closes the connection. -- Timeout unit in Seconds. @@ -86,9 +88,9 @@ feature -- Access do Result.is_verbose := is_verbose Result.verbose_level := verbose_level - Result.timeout := socket_timeout - Result.socket_recv_timeout := socket_recv_timeout - Result.keep_alive_timeout := keep_alive_timeout + Result.timeout_ns := socket_timeout_ns + Result.socket_recv_timeout_ns := socket_recv_timeout_ns + Result.keep_alive_timeout_ns := keep_alive_timeout_ns Result.max_keep_alive_requests := max_keep_alive_requests Result.is_secure := is_secure end @@ -166,28 +168,52 @@ feature -- Element change max_concurrent_connections_set : max_concurrent_connections = v end - set_socket_timeout (a_nb_seconds: like socket_timeout) + set_socket_timeout_ns (a_nano_seconds: like socket_timeout_ns) + -- Set `socket_timeout_ns' with `a_nano_seconds'. + require + is_valid_timeout_ns: is_valid_timeout_ns (a_nano_seconds) + do + socket_timeout_ns := a_nano_seconds + ensure + socket_timeout_ns_set: socket_timeout_ns = a_nano_seconds + end + + set_socket_recv_timeout_ns (a_nano_seconds: like socket_recv_timeout_ns) + -- Set `socket_recv_timeout_ns' with `a_nano_seconds'. + require + is_valid_timeout_ns: is_valid_timeout_ns (a_nano_seconds) + do + socket_recv_timeout_ns := a_nano_seconds + ensure + socket_recv_timeout_ns_set: socket_recv_timeout_ns = a_nano_seconds + end + + set_keep_alive_timeout_ns (a_nano_seconds: like keep_alive_timeout_ns) + -- Set `keep_alive_timeout_ns' with `a_nano_seconds'. + require + is_valid_timeout_ns: is_valid_timeout_ns (a_nano_seconds) + do + keep_alive_timeout_ns := a_nano_seconds + ensure + keep_alive_timeout_ns_set: keep_alive_timeout_ns = a_nano_seconds + end + + set_socket_timeout (a_nb_seconds: INTEGER) -- Set `socket_timeout' with `a_nb_seconds'. do - socket_timeout := a_nb_seconds - ensure - socket_timeout_set: socket_timeout = a_nb_seconds + set_socket_timeout_ns (seconds_to_nanoseconds (a_nb_seconds)) end - set_socket_recv_timeout (a_nb_seconds: like socket_recv_timeout) + set_socket_recv_timeout (a_nb_seconds: INTEGER) -- Set `socket_recv_timeout' with `a_nb_seconds'. do - socket_recv_timeout := a_nb_seconds - ensure - socket_recv_timeout_set: socket_recv_timeout = a_nb_seconds + set_socket_recv_timeout_ns (seconds_to_nanoseconds (a_nb_seconds)) end - set_keep_alive_timeout (a_seconds: like keep_alive_timeout) - -- Set `keep_alive_timeout' with `a_seconds'. + set_keep_alive_timeout (a_nb_seconds: INTEGER) + -- Set `keep_alive_timeout' with `a_nb_seconds'. do - keep_alive_timeout := a_seconds - ensure - keep_alive_timeout_set: keep_alive_timeout = a_seconds + set_keep_alive_timeout_ns (seconds_to_nanoseconds (a_nb_seconds)) end set_max_keep_alive_requests (nb: like max_keep_alive_requests) diff --git a/library/server/httpd/configuration/httpd_request_settings.e b/library/server/httpd/configuration/httpd_request_settings.e index 88c34270..3aba34ee 100644 --- a/library/server/httpd/configuration/httpd_request_settings.e +++ b/library/server/httpd/configuration/httpd_request_settings.e @@ -9,6 +9,9 @@ note expanded class HTTPD_REQUEST_SETTINGS +inherit + SOCKET_TIMEOUT_UTILITIES + feature -- Access is_verbose: BOOLEAN assign set_is_verbose @@ -20,13 +23,13 @@ feature -- Access is_secure: BOOLEAN assign set_is_secure -- Is using secure connection? i.e SSL? - timeout: INTEGER assign set_timeout + timeout_ns: NATURAL_64 assign set_timeout_ns -- Amount of seconds that the server waits for receipts and transmissions during communications. - socket_recv_timeout: INTEGER assign set_socket_recv_timeout + socket_recv_timeout_ns: NATURAL_64 assign set_socket_recv_timeout_ns -- Amount of seconds that the server waits for receiving data on socket during communications. - keep_alive_timeout: INTEGER assign set_keep_alive_timeout + keep_alive_timeout_ns: NATURAL_64 assign set_keep_alive_timeout_ns -- Keep-alive timeout, also known as persistent-connection timeout. -- Number of seconds the server waits after a request has been served before it closes the connection. -- Unit in Seconds. @@ -34,6 +37,29 @@ feature -- Access max_keep_alive_requests: INTEGER assign set_max_keep_alive_requests -- Maximum number of requests allowed per persistent connection. +feature -- Access: obsolete + + timeout: INTEGER assign set_timeout + obsolete + "Use `timeout_ns` [2018-10-29]" + do + Result := nanoseconds_to_seconds (timeout_ns) + end + + socket_recv_timeout: INTEGER assign set_socket_recv_timeout + obsolete + "Use `socket_recv_timeout_ns` [2018-10-29]" + do + Result := nanoseconds_to_seconds (socket_recv_timeout_ns) + end + + keep_alive_timeout: INTEGER assign set_keep_alive_timeout + obsolete + "Use `keep_alive_timeout_ns` [2018-10-29]" + do + Result := nanoseconds_to_seconds (keep_alive_timeout_ns) + end + feature -- Change set_is_verbose (b: BOOLEAN) @@ -54,24 +80,48 @@ feature -- Change is_secure := b end +feature -- Timeout change + + set_timeout_ns (a_timeout_in_nanoseconds: NATURAL_64) + -- Set `timeout_ns' to `a_timeout_in_nanoseconds'. + do + timeout_ns := a_timeout_in_nanoseconds + end + + set_socket_recv_timeout_ns (a_timeout_in_nanoseconds: NATURAL_64) + -- Set `socket_recv_timeout_ns' to `a_timeout_in_nanoseconds'. + do + socket_recv_timeout_ns := a_timeout_in_nanoseconds + end + + set_keep_alive_timeout_ns (a_timeout_in_nanoseconds: NATURAL_64) + -- Set `keep_alive_timeout_ns' to `a_timeout_in_nanoseconds'. + do + keep_alive_timeout_ns := a_timeout_in_nanoseconds + end + +feature -- Timeout change (in seconds) + set_timeout (a_timeout_in_seconds: INTEGER) -- Set `timeout' to `a_timeout_in_seconds'. do - timeout := a_timeout_in_seconds + set_timeout_ns (seconds_to_nanoseconds (a_timeout_in_seconds)) end set_socket_recv_timeout (a_timeout_in_seconds: INTEGER) -- Set `socket_recv_timeout' to `a_timeout_in_seconds'. do - socket_recv_timeout := a_timeout_in_seconds + set_socket_recv_timeout_ns (seconds_to_nanoseconds (a_timeout_in_seconds)) end set_keep_alive_timeout (a_timeout_in_seconds: INTEGER) -- Set `keep_alive_timeout' to `a_timeout_in_seconds'. do - keep_alive_timeout := a_timeout_in_seconds + set_keep_alive_timeout_ns (seconds_to_nanoseconds (a_timeout_in_seconds)) end +feature -- Change + set_max_keep_alive_requests (nb: like max_keep_alive_requests) -- Set `max_keep_alive_requests' with `nb' do @@ -79,7 +129,7 @@ feature -- Change end note - copyright: "2011-2016, 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 diff --git a/library/server/httpd/httpd_request_handler_i.e b/library/server/httpd/httpd_request_handler_i.e index c61a1759..87d1bf43 100644 --- a/library/server/httpd/httpd_request_handler_i.e +++ b/library/server/httpd/httpd_request_handler_i.e @@ -19,9 +19,9 @@ feature {NONE} -- Initialization do reset -- Import global request settings. - timeout := a_request_settings.timeout -- seconds - socket_recv_timeout := a_request_settings.socket_recv_timeout -- seconds - keep_alive_timeout := a_request_settings.keep_alive_timeout -- seconds + timeout_ns := a_request_settings.timeout_ns -- nanoseconds + socket_recv_timeout_ns := a_request_settings.socket_recv_timeout_ns -- nanoseconds + keep_alive_timeout_ns := a_request_settings.keep_alive_timeout_ns -- nanoseconds max_keep_alive_requests := a_request_settings.max_keep_alive_requests is_verbose := a_request_settings.is_verbose @@ -140,7 +140,7 @@ feature -- Settings is_persistent_connection_supported: BOOLEAN -- Is persistent connection supported? do - Result := {HTTPD_SERVER}.is_persistent_connection_supported and then + Result := {HTTPD_SERVER}.is_persistent_connection_supported and then max_keep_alive_requests /= 0 --| `-1` no limit end @@ -148,16 +148,16 @@ feature -- Settings -- Is next persistent connection supported? -- note: it is relevant only if `is_persistent_connection_supported' is True. - timeout: INTEGER -- seconds + timeout_ns: NATURAL_64 -- nanoseconds -- Amount of seconds that the server waits for receipts and transmissions during communications. - socket_recv_timeout: INTEGER -- seconds + socket_recv_timeout_ns: NATURAL_64 -- nanoseconds -- Amount of seconds that the server waits for receiving data on socket during communications. max_keep_alive_requests: INTEGER -- Maximum number of requests allowed per persistent connection. - keep_alive_timeout: INTEGER -- seconds + keep_alive_timeout_ns: NATURAL_64 -- nanoseconds -- Number of seconds for persistent connection timeout. feature -- Status report @@ -173,7 +173,7 @@ feature -- Status change has_error := True if m /= Void and then is_verbose then log (m.as_string_8, debug_level) - end + end end reset_error @@ -226,6 +226,10 @@ feature -- Execution do l_socket := client_socket + -- Set to expected `timeout_ns`. + l_socket.set_timeout_ns (timeout_ns) + l_socket.set_recv_timeout_ns (socket_recv_timeout_ns) + -- Compute remote info once for the persistent connection. create l_remote_info if attached l_socket.peer_address as l_addr then @@ -407,9 +411,9 @@ feature -- Parsing a_socket.readable then if a_is_reusing_connection then - a_socket.set_recv_timeout (keep_alive_timeout) -- in seconds! + a_socket.set_recv_timeout_ns (keep_alive_timeout_ns) -- in nanoseconds! else - a_socket.set_recv_timeout (socket_recv_timeout) -- FIXME: return a 408 Request Timeout response .. + a_socket.set_recv_timeout_ns (socket_recv_timeout_ns) -- FIXME: return a 408 Request Timeout response .. end if @@ -424,7 +428,7 @@ feature -- Parsing if not has_error then if a_is_reusing_connection then -- Restore normal recv timeout! - a_socket.set_recv_timeout (socket_recv_timeout) -- FIXME: return a 408 Request Timeout response .. + a_socket.set_recv_timeout_ns (socket_recv_timeout_ns) -- FIXME: return a 408 Request Timeout response .. end from line := next_line (a_socket) @@ -646,7 +650,7 @@ invariant request_header_attached: request_header /= Void note - copyright: "2011-2016, 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 diff --git a/library/server/httpd/httpd_server_i.e b/library/server/httpd/httpd_server_i.e index 9d306833..bc5344dc 100644 --- a/library/server/httpd/httpd_server_i.e +++ b/library/server/httpd/httpd_server_i.e @@ -109,9 +109,9 @@ feature -- Execution log (" - port = " + configuration.http_server_port.out) log (" - max_tcp_clients = " + configuration.max_tcp_clients.out) log (" - max_concurrent_connections = " + configuration.max_concurrent_connections.out) - log (" - socket_timeout = " + configuration.socket_timeout.out + " seconds") - log (" - socket_recv_timeout = " + configuration.socket_recv_timeout.out + " seconds") - log (" - keep_alive_timeout = " + configuration.keep_alive_timeout.out + " seconds") + log (" - socket_timeout = " + timeout_representation (configuration.socket_timeout_ns)) + log (" - socket_recv_timeout = " + timeout_representation (configuration.socket_recv_timeout_ns)) + log (" - keep_alive_timeout = " + timeout_representation (configuration.keep_alive_timeout_ns)) log (" - max_keep_alive_requests = " + configuration.max_keep_alive_requests.out) if configuration.has_secure_support then if configuration.is_secure then @@ -366,8 +366,25 @@ feature -- Output end end + timeout_representation (a_ns: NATURAL_64): STRING + do + if 1_000 * (a_ns // 1_000) = a_ns then + if 1_000_000 * (a_ns // 1_000_000) = a_ns then + if 1_000_000_000 * (a_ns // 1_000_000_000) = a_ns then + Result := (a_ns // 1_000_000_000).out + " seconds" + else + Result := (a_ns // 1_000_000).out + " milliseconds" + end + else + Result := (a_ns // 1_000).out + " microseconds" + end + else + Result := a_ns.out + " nanoseconds" + end + end + note - copyright: "2011-2016, 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 diff --git a/library/server/wsf/connector/standalone/wsf_standalone_service_launcher.e b/library/server/wsf/connector/standalone/wsf_standalone_service_launcher.e index 714b926d..aab38ba7 100644 --- a/library/server/wsf/connector/standalone/wsf_standalone_service_launcher.e +++ b/library/server/wsf/connector/standalone/wsf_standalone_service_launcher.e @@ -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 diff --git a/library/server/wsf/connector/standalone_websocket/websocket/event/web_socket_event_i.e b/library/server/wsf/connector/standalone_websocket/websocket/event/web_socket_event_i.e index daff711c..73f79912 100644 --- a/library/server/wsf/connector/standalone_websocket/websocket/event/web_socket_event_i.e +++ b/library/server/wsf/connector/standalone_websocket/websocket/event/web_socket_event_i.e @@ -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 diff --git a/library/server/wsf/connector/standalone_websocket/websocket/web_socket.e b/library/server/wsf/connector/standalone_websocket/websocket/web_socket.e index 603a01f4..741b8934 100644 --- a/library/server/wsf/connector/standalone_websocket/websocket/web_socket.e +++ b/library/server/wsf/connector/standalone_websocket/websocket/web_socket.e @@ -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 diff --git a/library/server/wsf/src/service/wsf_service_launcher_options.e b/library/server/wsf/src/service/wsf_service_launcher_options.e index 3a6d6c63..7e53829f 100644 --- a/library/server/wsf/src/service/wsf_service_launcher_options.e +++ b/library/server/wsf/src/service/wsf_service_launcher_options.e @@ -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