From 4c496d8182b5f3a5db6ca8fd763bab444e39f48a Mon Sep 17 00:00:00 2001 From: Garrett D'Amore Date: Tue, 24 Jan 2017 08:45:53 -0800 Subject: Implement reconnect timer including backoff. This allows us to enable the last test case for compat_reqrep. --- src/core/endpt.c | 35 ++++++++++++++++++++++++++--------- src/core/socket.c | 2 +- tests/compat_reqrep.c | 9 ++------- 3 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/core/endpt.c b/src/core/endpt.c index 5a642a2f..9aae89eb 100644 --- a/src/core/endpt.c +++ b/src/core/endpt.c @@ -161,11 +161,31 @@ nni_dialer(void *arg) nni_ep *ep = arg; int rv; nni_time cooldown; + nni_duration maxrtime; + nni_duration defrtime; + nni_duration rtime; nni_mtx *mx = &ep->ep_sock->s_mx; + nni_mtx_lock(mx); + defrtime = ep->ep_sock->s_reconn; + if ((maxrtime = ep->ep_sock->s_reconnmax) == 0) { + maxrtime = defrtime; + } + nni_mtx_unlock(mx); + for (;;) { nni_mtx_lock(mx); + if ((defrtime != ep->ep_sock->s_reconn) || + (maxrtime != ep->ep_sock->s_reconnmax)) { + // Times changed, so reset them. + defrtime = ep->ep_sock->s_reconn; + if ((maxrtime = ep->ep_sock->s_reconnmax) == 0) { + maxrtime = defrtime; + } + rtime = defrtime; + } while ((!ep->ep_close) && (ep->ep_pipe != NULL)) { + rtime = defrtime; nni_cv_wait(&ep->ep_cv); } if (ep->ep_close) { @@ -179,22 +199,19 @@ nni_dialer(void *arg) case 0: // good connection continue; - case NNG_ENOMEM: - cooldown = 1000000; - break; case NNG_ECLOSED: return; default: - // XXX: THIS NEEDS TO BE A PROPER BACKOFF. - cooldown = 1000000; + cooldown = nni_clock() + rtime; + rtime *= 2; + if ((maxrtime >= defrtime) && (rtime > maxrtime)) { + rtime = maxrtime; + } break; } // we inject a delay so we don't just spin hard on - // errors like connection refused. For NNG_ENOMEM, we - // wait even longer, since the system needs time to - // release resources. - cooldown += nni_clock(); + // errors like connection refused. nni_mtx_lock(mx); while (!ep->ep_close) { // We need a different condvar... diff --git a/src/core/socket.c b/src/core/socket.c index 24078941..b0ce172f 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -274,7 +274,7 @@ nni_sock_open(nni_sock **sockp, uint16_t pnum) sock->s_rcvtimeo = -1; sock->s_closing = 0; sock->s_reconn = NNI_SECOND; - sock->s_reconnmax = NNI_SECOND; + sock->s_reconnmax = 0; sock->s_reapexit = 0; NNI_LIST_INIT(&sock->s_pipes, nni_pipe, p_node); NNI_LIST_INIT(&sock->s_reaps, nni_pipe, p_node); diff --git a/tests/compat_reqrep.c b/tests/compat_reqrep.c index a418b8d9..51ff4fb8 100644 --- a/tests/compat_reqrep.c +++ b/tests/compat_reqrep.c @@ -121,29 +121,24 @@ int main () test_close (rep1); -#if 0 // The default reconnect interval is waaay to large for this to pass. /* Check sending a request when the peer is not available. (It should be sent immediatelly when the peer comes online rather than relying on the resend algorithm. */ req1 = test_socket (AF_SP, NN_REQ); timeo = 10; - rc = nn_setsockopt (req1, NN_SOL_SOCKET, NN_RECONNECT_IVL, - &timeo, sizeof (timeo)); + test_setsockopt (req1, NN_SOL_SOCKET, NN_RECONNECT_IVL, &timeo, sizeof (timeo)); test_send (req1, "ABC"); test_connect (req1, SOCKET_ADDRESS); rep1 = test_socket (AF_SP, NN_REP); test_bind (rep1, SOCKET_ADDRESS); timeo = 500; - rc = nn_setsockopt (rep1, NN_SOL_SOCKET, NN_RCVTIMEO, - &timeo, sizeof (timeo)); - printf("RC = %d errno %d (%s)\n", rc, errno, strerror(errno)); + test_setsockopt (rep1, NN_SOL_SOCKET, NN_RCVTIMEO, &timeo, sizeof (timeo)); errno_assert (rc == 0); test_recv (rep1, "ABC"); test_close (req1); test_close (rep1); -#endif /* Check removing socket request sent to (It should be sent immediatelly to other peer rather than relying -- cgit v1.2.3-70-g09d2