From f23c7756b6c75f571e28346c6ee1466f108932c8 Mon Sep 17 00:00:00 2001 From: "E. Scott Daniels" Date: Tue, 17 Sep 2019 13:58:33 -0400 Subject: [PATCH] Change connection mode to asynchronous The default mode for NNG is to make TCP connections in a synchronous or blocking manner (opposite of Nanomsg). This change causes RMR to invoke the NNG connection function (dialer) with the non-blocking flag set. This will likely result in soft failures (retries) on message send attempts until the connection is completed. The original blocking mode can be enabled by setting the RMR_ASYNC_CONN environment variable to 0 which will turn this off and cause connections to block. Absense of the variable, or setting it to 1, causes asynch mode to be on. This addresses the issue described in RICPLT-2215. Signed-off-by: E. Scott Daniels Change-Id: I4f544d772227b784efd1f7146a18921b91ae7f8e --- CMakeLists.txt | 2 +- doc/src/man/rmr.7.xfm | 7 +++++++ src/bindings/rmr-python/Dockerfile-Unit-Test | 7 +++++-- src/rmr/nng/src/rtable_nng_static.c | 16 ++++++++++++++-- 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bb91e10..b4122d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,7 +35,7 @@ project( rmr LANGUAGES C ) cmake_minimum_required( VERSION 3.5 ) set( major_version "1" ) # should be automatically populated from git tag later, but until CI process sets a tag we use this -set( minor_version "6" ) +set( minor_version "7" ) set( patch_level "0" ) set( install_root "${CMAKE_INSTALL_PREFIX}" ) diff --git a/doc/src/man/rmr.7.xfm b/doc/src/man/rmr.7.xfm index 5de226f..1d87f73 100644 --- a/doc/src/man/rmr.7.xfm +++ b/doc/src/man/rmr.7.xfm @@ -74,6 +74,13 @@ The following is a list of the various environment variables, what they control and the defaults which RMr uses if undefined. &beg_dlist(.75i : ^&bold_font ) +&di(RMR_ASYNC_CONN) Allows the asynch connection mode to be turned off (by setting the + value to 0. When set to 1, or missing from the environment, RMR will invoke the + connection interface in the transport mechanism using the non-blocking (asynch) + mode. This will likely result in many "soft failures" (retry) until the connection + is established, but allows the application to continue unimpeeded should the + connection be slow to set up. + &di(RMR_BIND_IF) This provides the interface that RMr will bind listen ports to allowing for a single interface to be used rather than listening across all interfaces. This should be the IP address assigned to the interface that RMr should listen diff --git a/src/bindings/rmr-python/Dockerfile-Unit-Test b/src/bindings/rmr-python/Dockerfile-Unit-Test index 9cfe15c..d9ee412 100644 --- a/src/bindings/rmr-python/Dockerfile-Unit-Test +++ b/src/bindings/rmr-python/Dockerfile-Unit-Test @@ -16,9 +16,12 @@ # ================================================================================== FROM python:3.7-alpine +# the alpine image keeps changing; if it fails try searching: +# https://nexus3.o-ran-sc.org/#browse/search=keyword%3Dalpine3 +# # copy NNG and rmr out of the CI builder nng -COPY --from=nexus3.o-ran-sc.org:10004/bldr-alpine3:3-a3.9 /usr/local/lib64/libnng.so /usr/local/lib64/libnng.so -COPY --from=nexus3.o-ran-sc.org:10004/bldr-alpine3:3-a3.9 /usr/local/lib64/librmr_nng.so /usr/local/lib64/librmr_nng.so +COPY --from=nexus3.o-ran-sc.org:10004/bldr-alpine3:5-a3.9 /usr/local/lib64/libnng.so /usr/local/lib64/libnng.so +COPY --from=nexus3.o-ran-sc.org:10004/bldr-alpine3:5-a3.9 /usr/local/lib64/librmr_nng.so /usr/local/lib64/librmr_nng.so COPY rmr/ /tmp/rmr COPY tests/ /tmp/tests diff --git a/src/rmr/nng/src/rtable_nng_static.c b/src/rmr/nng/src/rtable_nng_static.c index da4101b..4f413be 100644 --- a/src/rmr/nng/src/rtable_nng_static.c +++ b/src/rmr/nng/src/rtable_nng_static.c @@ -61,18 +61,30 @@ */ //static int uta_link2( char* target, nng_socket* nn_sock, nng_dialer* dialer, pthread_mutex* gate ) { static int uta_link2( endpoint_t* ep ) { + static int flags = -1; + char* target; nng_socket* nn_sock; nng_dialer* dialer; char conn_info[NNG_MAXADDRLEN]; // string to give to nano to make the connection char* addr; int state = FALSE; + char* tok; if( ep == NULL ) { return FALSE; } - target = ep->addr; + if( flags < 0 ) { + tok = getenv( "RMR_ASYNC_CONN" ); + if( tok == NULL || *tok == '1' ) { + flags = NNG_FLAG_NONBLOCK; // start dialer asynch + } else { + flags = NO_FLAGS; + } + } + + target = ep->name; // always give name to transport so chaning dest IP does not break reconnect nn_sock = &ep->nn_sock; dialer = &ep->dialer; @@ -110,7 +122,7 @@ static int uta_link2( endpoint_t* ep ) { nng_dialer_setopt_ms( *dialer, NNG_OPT_RECONNMAXT, 2000 ); // cap backoff on retries to reasonable amount (2s) nng_dialer_setopt_ms( *dialer, NNG_OPT_RECONNMINT, 100 ); // start retry 100m after last failure with 2s cap - if( (state = nng_dialer_start( *dialer, NO_FLAGS )) != 0 ) { // can fail immediatly (unlike nanomsg) + if( (state = nng_dialer_start( *dialer, flags )) != 0 ) { // can fail immediatly (unlike nanomsg) pthread_mutex_unlock( &ep->gate ); fprintf( stderr, "[WRN] rmr: unable to create link to target: %s: %s\n", target, nng_strerror( state ) ); nng_close( *nn_sock ); -- 2.16.6