From c85f737ae003544f9d17e7731b84631d1c018a62 Mon Sep 17 00:00:00 2001 From: rkhapov Date: Tue, 15 Oct 2024 10:07:43 +0000 Subject: [PATCH 1/3] machinarium: add advice tcp usr timeout fn The value of tcp user timeout should be computed from keepalive values. This patch adds advice function to machinarium for formulae of keepalive + interval + probes - 0.5 Signed-off-by: rkhapov --- stress/CMakeLists.txt | 2 +- test/CMakeLists.txt | 1 + test/machinarium/test_advice_keepalive_usr_timeout.c | 8 ++++++++ test/odyssey_test.c | 2 ++ third_party/machinarium/sources/io.c | 6 ++++++ third_party/machinarium/sources/machinarium.h | 3 +++ third_party/machinarium/sources/machinarium_private.h | 1 + third_party/machinarium/sources/socket.c | 8 ++++++++ third_party/machinarium/sources/socket.h | 2 ++ 9 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 test/machinarium/test_advice_keepalive_usr_timeout.c diff --git a/stress/CMakeLists.txt b/stress/CMakeLists.txt index b63f92a64..a76e4be41 100644 --- a/stress/CMakeLists.txt +++ b/stress/CMakeLists.txt @@ -13,7 +13,7 @@ if(THREADS_HAVE_PTHREAD_ARG) set_property(TARGET ${od_stress_binary} PROPERTY INTERFACE_COMPILE_OPTIONS "-pthread") endif() -target_link_libraries(${od_stress_binary} ${od_libraries} ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries(${od_stress_binary} ${od_libraries} ${CMAKE_THREAD_LIBS_INIT} m) if (BUILD_COMPRESSION) target_link_libraries(${od_stress_binary} ${compression_libraries}) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 3b1fea562..6d09b84c2 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -40,6 +40,7 @@ set(od_test_src machinarium/test_connect_cancel1.c machinarium/test_accept_timeout.c machinarium/test_accept_cancel.c + machinarium/test_advice_keepalive_usr_timeout.c machinarium/test_getaddrinfo0.c machinarium/test_getaddrinfo1.c machinarium/test_getaddrinfo2.c diff --git a/test/machinarium/test_advice_keepalive_usr_timeout.c b/test/machinarium/test_advice_keepalive_usr_timeout.c new file mode 100644 index 000000000..b4f02753d --- /dev/null +++ b/test/machinarium/test_advice_keepalive_usr_timeout.c @@ -0,0 +1,8 @@ +#include +#include + +void machinarium_test_advice_keepalive_usr_timeout(void) +{ + test(machine_advice_keepalive_usr_timeout(100, 10, 3) == 129); + test(machine_advice_keepalive_usr_timeout(15, 10, 5) == 64); +} \ No newline at end of file diff --git a/test/odyssey_test.c b/test/odyssey_test.c index 562ade469..003e8ac45 100644 --- a/test/odyssey_test.c +++ b/test/odyssey_test.c @@ -55,6 +55,7 @@ extern void machinarium_test_connect_cancel0(void); extern void machinarium_test_connect_cancel1(void); extern void machinarium_test_accept_timeout(void); extern void machinarium_test_accept_cancel(void); +extern void machinarium_test_advice_keepalive_usr_timeout(void); extern void machinarium_test_getaddrinfo0(void); extern void machinarium_test_getaddrinfo1(void); extern void machinarium_test_getaddrinfo2(void); @@ -134,6 +135,7 @@ int main(int argc, char *argv[]) odyssey_test(machinarium_test_connect_cancel1); odyssey_test(machinarium_test_accept_timeout); odyssey_test(machinarium_test_accept_cancel); + odyssey_test(machinarium_test_advice_keepalive_usr_timeout); odyssey_test(machinarium_test_getaddrinfo0); odyssey_test(machinarium_test_getaddrinfo1); odyssey_test(machinarium_test_getaddrinfo2); diff --git a/third_party/machinarium/sources/io.c b/third_party/machinarium/sources/io.c index 443e7103b..19091b18a 100644 --- a/third_party/machinarium/sources/io.c +++ b/third_party/machinarium/sources/io.c @@ -261,6 +261,12 @@ MACHINE_API int machine_set_keepalive(machine_io_t *obj, int enable, int delay, return 0; } +MACHINE_API int machine_advice_keepalive_usr_timeout(int delay, int interval, + int probes) +{ + return mm_socket_advice_keepalive_usr_timeout(delay, interval, probes); +} + MACHINE_API int machine_io_attach(machine_io_t *obj) { mm_io_t *io = mm_cast(mm_io_t *, obj); diff --git a/third_party/machinarium/sources/machinarium.h b/third_party/machinarium/sources/machinarium.h index fe46e348b..c0c5b0a02 100644 --- a/third_party/machinarium/sources/machinarium.h +++ b/third_party/machinarium/sources/machinarium.h @@ -201,6 +201,9 @@ MACHINE_API int machine_set_keepalive(machine_io_t *, int enable, int delay, int interval, int probes, int usr_timeout); +MACHINE_API int machine_advice_keepalive_usr_timeout(int delay, int interval, + int probes); + MACHINE_API int machine_set_tls(machine_io_t *, machine_tls_t *, uint32_t); MACHINE_API int machine_set_compression(machine_io_t *, char algorithm); diff --git a/third_party/machinarium/sources/machinarium_private.h b/third_party/machinarium/sources/machinarium_private.h index 0a35e167a..040765e05 100644 --- a/third_party/machinarium/sources/machinarium_private.h +++ b/third_party/machinarium/sources/machinarium_private.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/third_party/machinarium/sources/socket.c b/third_party/machinarium/sources/socket.c index 01e9bfa81..da8813e26 100644 --- a/third_party/machinarium/sources/socket.c +++ b/third_party/machinarium/sources/socket.c @@ -77,6 +77,14 @@ int mm_socket_set_keepalive(int fd, int enable, int delay, int interval, return MM_OK_RETCODE; } +int mm_socket_advice_keepalive_usr_timeout(int delay, int interval, + int keep_count) +{ + // https://habr.com/ru/articles/700470/ + double v = delay + (double)interval * keep_count - 0.5L; + return (int)floor(v); +} + int mm_socket_set_nosigpipe(int fd, int enable) { #if defined(SO_NOSIGPIPE) diff --git a/third_party/machinarium/sources/socket.h b/third_party/machinarium/sources/socket.h index 4b99d861e..97d333eb0 100644 --- a/third_party/machinarium/sources/socket.h +++ b/third_party/machinarium/sources/socket.h @@ -13,6 +13,8 @@ int mm_socket_set_nonblock(int, int); int mm_socket_set_nodelay(int, int); int mm_socket_set_keepalive(int fd, int enable, int delay, int interval, int keep_count, int usr_timeout); +int mm_socket_advice_keepalive_usr_timeout(int delay, int interval, + int keep_count); int mm_socket_set_nosigpipe(int, int); int mm_socket_set_reuseaddr(int, int); int mm_socket_set_reuseport(int, int); From 11c119590e3d74d8c33ae93dd9f5b0c33e9b94ed Mon Sep 17 00:00:00 2001 From: rkhapov Date: Tue, 15 Oct 2024 10:14:51 +0000 Subject: [PATCH 2/3] sources/config_reader.c: use advice tcp usr timeout Now, default value of keepalive_usr_timeout will lead to adviced value of tcp usr timeout, computed with values of keepalive. Signed-off-by: rkhapov --- documentation/configuration.md | 6 +++++- sources/config_reader.c | 10 ++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/documentation/configuration.md b/documentation/configuration.md index 06dcbeef1..2051b30b7 100644 --- a/documentation/configuration.md +++ b/documentation/configuration.md @@ -244,7 +244,11 @@ TCP keep-alive probes to send before giving up and killing the connection i #### keepalive_usr_timeout *integer* When the value is greater than 0, it specifies the maximum amount of time in milliseconds that transmitted data may remain unacknowledged before TCP will forcibly close the -corresponding connection +corresponding connection. + +When the value is negaive, the default system user timeout will be used. + +When no value or 0 is provided `floor(keepalive + keepalive_keep_interval * keepalive_probes - 0.5)` is used. `keepalive_usr_timeout 7` diff --git a/sources/config_reader.c b/sources/config_reader.c index 9869f15cf..618365f2d 100644 --- a/sources/config_reader.c +++ b/sources/config_reader.c @@ -2815,6 +2815,16 @@ static int od_config_reader_parse(od_config_reader_t *reader, config->client_max_routing = config->workers * 16; } + if (config->keepalive_usr_timeout == 0) { + config->keepalive_usr_timeout = + machine_advice_keepalive_usr_timeout( + config->keepalive, + config->keepalive_keep_interval, + config->keepalive_probes); + } else if (config->keepalive_usr_timeout < 0) { + config->keepalive_usr_timeout = 0; + } + return 0; } From 2844d1df203a13d9ad1e066e4008cadac57a4941 Mon Sep 17 00:00:00 2001 From: rkhapov Date: Tue, 15 Oct 2024 10:21:52 +0000 Subject: [PATCH 3/3] test_advice_keepalive_usr_timeout.c: fix milliseconds According to `man 7 tcp`, delay and interval values are presented seconds. But tcp user timeout are presented in milliseconds. So formula fixed. Signed-off-by: rkhapov --- sources/config_reader.c | 23 +++++++++++-------- .../test_advice_keepalive_usr_timeout.c | 4 ++-- third_party/machinarium/sources/socket.c | 6 +++-- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/sources/config_reader.c b/sources/config_reader.c index 618365f2d..3a69f2c6c 100644 --- a/sources/config_reader.c +++ b/sources/config_reader.c @@ -2366,6 +2366,19 @@ static int od_config_reader_hba_import(od_config_reader_t *config_reader) return rc; } +static void od_config_setup_default_tcp_usr_timeout(od_config_t *config) +{ + if (config->keepalive_usr_timeout == 0) { + config->keepalive_usr_timeout = + machine_advice_keepalive_usr_timeout( + config->keepalive, + config->keepalive_keep_interval, + config->keepalive_probes); + } else if (config->keepalive_usr_timeout < 0) { + config->keepalive_usr_timeout = 0; + } +} + static int od_config_reader_parse(od_config_reader_t *reader, od_extention_t *extentions) { @@ -2815,15 +2828,7 @@ static int od_config_reader_parse(od_config_reader_t *reader, config->client_max_routing = config->workers * 16; } - if (config->keepalive_usr_timeout == 0) { - config->keepalive_usr_timeout = - machine_advice_keepalive_usr_timeout( - config->keepalive, - config->keepalive_keep_interval, - config->keepalive_probes); - } else if (config->keepalive_usr_timeout < 0) { - config->keepalive_usr_timeout = 0; - } + od_config_setup_default_tcp_usr_timeout(config); return 0; } diff --git a/test/machinarium/test_advice_keepalive_usr_timeout.c b/test/machinarium/test_advice_keepalive_usr_timeout.c index b4f02753d..fa4eff645 100644 --- a/test/machinarium/test_advice_keepalive_usr_timeout.c +++ b/test/machinarium/test_advice_keepalive_usr_timeout.c @@ -3,6 +3,6 @@ void machinarium_test_advice_keepalive_usr_timeout(void) { - test(machine_advice_keepalive_usr_timeout(100, 10, 3) == 129); - test(machine_advice_keepalive_usr_timeout(15, 10, 5) == 64); + test(machine_advice_keepalive_usr_timeout(100, 10, 3) == 129500); + test(machine_advice_keepalive_usr_timeout(15, 10, 5) == 64500); } \ No newline at end of file diff --git a/third_party/machinarium/sources/socket.c b/third_party/machinarium/sources/socket.c index da8813e26..d96415c77 100644 --- a/third_party/machinarium/sources/socket.c +++ b/third_party/machinarium/sources/socket.c @@ -81,8 +81,10 @@ int mm_socket_advice_keepalive_usr_timeout(int delay, int interval, int keep_count) { // https://habr.com/ru/articles/700470/ - double v = delay + (double)interval * keep_count - 0.5L; - return (int)floor(v); + // delay, interval are in seconds + // usr timeout in milliseconds + // see man 7 tcp + return 1000 * (delay + interval * keep_count) - 500; } int mm_socket_set_nosigpipe(int fd, int enable)