Change connection mode to asynchronous 67/967/2 1.7.0
authorE. Scott Daniels <daniels@research.att.com>
Tue, 17 Sep 2019 17:58:33 +0000 (13:58 -0400)
committerE. Scott Daniels <daniels@research.att.com>
Tue, 17 Sep 2019 20:30:48 +0000 (16:30 -0400)
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 <daniels@research.att.com>
Change-Id: I4f544d772227b784efd1f7146a18921b91ae7f8e

CMakeLists.txt
doc/src/man/rmr.7.xfm
src/bindings/rmr-python/Dockerfile-Unit-Test
src/rmr/nng/src/rtable_nng_static.c

index bb91e10..b4122d7 100644 (file)
@@ -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}" )
index 5de226f..1d87f73 100644 (file)
@@ -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
index 9cfe15c..d9ee412 100644 (file)
 # ==================================================================================
 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
index da4101b..4f413be 100644 (file)
 */
 //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 );