[Asterisk-code-review] res xmpp: Use incremental backoff when a read error occurs (asterisk[14])

Joshua Colp asteriskteam at digium.com
Tue Mar 28 15:41:25 CDT 2017


Joshua Colp has submitted this change and it was merged. ( https://gerrit.asterisk.org/5303 )

Change subject: res_xmpp: Use incremental backoff when a read error occurs
......................................................................


res_xmpp: Use incremental backoff when a read error occurs

If a read error occurs, we immediately attempt a reconnect without any
delay. Instead, let's sleep and backoff up to 60 seconds before we try
again.

ASTERISK-24712 #close
Reported by: Matthias Urlichs

Change-Id: I6fe10ef4734837727437beab715e336777f13f48
---
M res/res_xmpp.c
1 file changed, 21 insertions(+), 1 deletion(-)

Approvals:
  Kevin Harwell: Looks good to me, approved
  Anonymous Coward #1000019: Verified
  Joshua Colp: Looks good to me, but someone else must approve



diff --git a/res/res_xmpp.c b/res/res_xmpp.c
index a80c2ed..dadde98 100644
--- a/res/res_xmpp.c
+++ b/res/res_xmpp.c
@@ -3595,6 +3595,7 @@
 {
 	if ((client->thread != AST_PTHREADT_NULL) && !pthread_equal(pthread_self(), client->thread)) {
 		xmpp_client_change_state(client, XMPP_STATE_DISCONNECTING);
+		pthread_cancel(client->thread);
 		pthread_join(client->thread, NULL);
 		client->thread = AST_PTHREADT_NULL;
 	}
@@ -3774,11 +3775,26 @@
 	return IKS_OK;
 }
 
+static void sleep_with_backoff(unsigned int *sleep_time)
+{
+	/* We're OK with our thread dying here */
+	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+
+	sleep(*sleep_time);
+	*sleep_time = MIN(60, *sleep_time * 2);
+
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+}
+
 /*! \brief XMPP client connection thread */
 static void *xmpp_client_thread(void *data)
 {
 	struct ast_xmpp_client *client = data;
 	int res = IKS_NET_RWERR;
+	unsigned int sleep_time = 1;
+
+	/* We only allow cancellation while sleeping */
+	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
 
 	do {
 		if (client->state == XMPP_STATE_DISCONNECTING) {
@@ -3789,7 +3805,7 @@
 		if (res == IKS_NET_RWERR || client->timeout == 0) {
 			ast_debug(3, "[%s] Connecting\n", client->name);
 			if ((res = xmpp_client_reconnect(client)) != IKS_OK) {
-				sleep(4);
+				sleep_with_backoff(&sleep_time);
 				res = IKS_NET_RWERR;
 			}
 			continue;
@@ -3828,6 +3844,8 @@
 			}
 		} else if (res == IKS_NET_RWERR) {
 			ast_log(LOG_WARNING, "[%s] Socket read error\n", client->name);
+			ast_xmpp_client_disconnect(client);
+			sleep_with_backoff(&sleep_time);
 		} else if (res == IKS_NET_NOSOCK) {
 			ast_log(LOG_WARNING, "[%s] No socket\n", client->name);
 		} else if (res == IKS_NET_NOCONN) {
@@ -3840,6 +3858,8 @@
 			ast_log(LOG_WARNING, "[%s] Dropped?\n", client->name);
 		} else if (res == IKS_NET_UNKNOWN) {
 			ast_debug(5, "[%s] Unknown\n", client->name);
+		} else if (res == IKS_OK) {
+			sleep_time = 1;
 		}
 
 	} while (1);

-- 
To view, visit https://gerrit.asterisk.org/5303
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I6fe10ef4734837727437beab715e336777f13f48
Gerrit-PatchSet: 2
Gerrit-Project: asterisk
Gerrit-Branch: 14
Gerrit-Owner: Sean Bright <sean.bright at gmail.com>
Gerrit-Reviewer: Anonymous Coward #1000019
Gerrit-Reviewer: Joshua Colp <jcolp at digium.com>
Gerrit-Reviewer: Kevin Harwell <kharwell at digium.com>



More information about the asterisk-code-review mailing list