From: Niels Provos Date: Sat, 9 Dec 2006 01:41:57 +0000 (+0000) Subject: support retrying for connections; from dug song X-Git-Tag: release-2.0.1-alpha~675 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=852d05a3c093ecaaacffb5ee339307782f706c96;p=libevent support retrying for connections; from dug song small tweaks from me. svn:r297 --- diff --git a/evhttp.h b/evhttp.h index c26fbb8d..6fa3e976 100644 --- a/evhttp.h +++ b/evhttp.h @@ -160,6 +160,10 @@ void evhttp_connection_free(struct evhttp_connection *evcon); void evhttp_connection_set_timeout(struct evhttp_connection *evcon, int timeout_in_secs); +/* Sets the retry limit for this connection - -1 repeats indefnitely */ +void evhttp_connection_set_retries(struct evhttp_connection *evcon, + int retry_max); + /* The connection gets ownership of the request */ int evhttp_make_request(struct evhttp_connection *evcon, struct evhttp_request *req, diff --git a/http-internal.h b/http-internal.h index a7cefbf8..69fc39ae 100644 --- a/http-internal.h +++ b/http-internal.h @@ -53,6 +53,8 @@ struct evhttp_connection { #define EVHTTP_CON_CLOSEDETECT 0x0004 /* detecting if persistent close */ int timeout; /* timeout in seconds for events */ + int retry_cnt; /* retry count */ + int retry_max; /* maximum number of retries */ enum evhttp_connection_state state; diff --git a/http.c b/http.c index 3ef22641..123b1c21 100644 --- a/http.c +++ b/http.c @@ -733,6 +733,15 @@ evhttp_connection_stop_detectclose(struct evhttp_connection *evcon) event_del(&evcon->ev); } +static void +evhttp_connection_retry(int fd, short what, void *arg) +{ + struct evhttp_connection *evcon = arg; + + evcon->state = EVCON_DISCONNECTED; + evhttp_connection_connect(evcon); +} + /* * Call back for asynchronous connection attempt. */ @@ -769,6 +778,8 @@ evhttp_connectioncb(int fd, short what, void *arg) event_debug(("%s: connected to \"%s:%d\" on %d\n", __func__, evcon->address, evcon->port, evcon->fd)); + /* Reset the retry count as we were successful in connecting */ + evcon->retry_cnt = 0; evcon->state = EVCON_CONNECTED; /* try to start requests that have queued up on this connection */ @@ -776,6 +787,13 @@ evhttp_connectioncb(int fd, short what, void *arg) return; cleanup: + if (evcon->retry_max < 0 || evcon->retry_cnt < evcon->retry_max) { + evtimer_set(&evcon->ev, evhttp_connection_retry, evcon); + evhttp_add_event(&evcon->ev, 2 << evcon->retry_cnt, + HTTP_CONNECT_TIMEOUT); + evcon->retry_cnt++; + return; + } evhttp_connection_reset(evcon); /* for now, we just signal all requests by executing their callbacks */ @@ -1188,6 +1206,7 @@ evhttp_connection_new(const char *address, unsigned short port) evcon->port = port; evcon->timeout = -1; + evcon->retry_cnt = evcon->retry_max = 0; if ((evcon->address = strdup(address)) == NULL) { event_warn("%s: strdup failed", __func__); @@ -1222,6 +1241,13 @@ evhttp_connection_set_timeout(struct evhttp_connection *evcon, evcon->timeout = timeout_in_secs; } +void +evhttp_connection_set_retries(struct evhttp_connection *evcon, + int retry_max) +{ + evcon->retry_max = retry_max; +} + int evhttp_connection_connect(struct evhttp_connection *evcon) {