dovecot-2.2: lib-http: client: Implemented support for connectio...
dovecot at dovecot.org
dovecot at dovecot.org
Wed Sep 10 10:45:56 UTC 2014
details: http://hg.dovecot.org/dovecot-2.2/rev/4412508cbc59
changeset: 17775:4412508cbc59
user: Stephan Bosch <stephan at rename-it.nl>
date: Wed Sep 10 13:39:37 2014 +0300
description:
lib-http: client: Implemented support for connection failure backoff.
diffstat:
src/lib-http/http-client-peer.c | 65 +++++++++++++++++++++++++++++++++++--
src/lib-http/http-client-private.h | 9 ++++-
src/lib-http/http-client.c | 4 ++
src/lib-http/http-client.h | 3 +
4 files changed, 75 insertions(+), 6 deletions(-)
diffs (187 lines):
diff -r 650629de6a73 -r 4412508cbc59 src/lib-http/http-client-peer.c
--- a/src/lib-http/http-client-peer.c Wed Sep 10 13:39:37 2014 +0300
+++ b/src/lib-http/http-client-peer.c Wed Sep 10 13:39:37 2014 +0300
@@ -2,6 +2,7 @@
#include "lib.h"
#include "net.h"
+#include "time-util.h"
#include "str.h"
#include "hash.h"
#include "array.h"
@@ -78,7 +79,8 @@
*/
static void
-http_client_peer_connect(struct http_client_peer *peer, unsigned int count)
+http_client_peer_do_connect(struct http_client_peer *peer,
+ unsigned int count)
{
unsigned int i;
@@ -89,6 +91,42 @@
}
}
+
+static void
+http_client_peer_connect_backoff(struct http_client_peer *peer)
+{
+ i_assert(peer->to_backoff != NULL);
+
+ http_client_peer_debug(peer,
+ "Backoff timer expired");
+
+ timeout_remove(&peer->to_backoff);
+ http_client_peer_do_connect(peer, 1);
+}
+
+static void
+http_client_peer_connect(struct http_client_peer *peer, unsigned int count)
+{
+ if (peer->to_backoff != NULL)
+ return;
+
+ if (peer->last_failure.tv_sec > 0) {
+ int backoff_time_spent =
+ timeval_diff_msecs(&ioloop_timeval, &peer->last_failure);
+ if (backoff_time_spent < (int)peer->backoff_time_msecs) {
+ http_client_peer_debug(peer,
+ "Starting backoff timer for %d msecs",
+ peer->backoff_time_msecs - backoff_time_spent);
+ peer->to_backoff = timeout_add
+ ((unsigned int)(peer->backoff_time_msecs - backoff_time_spent),
+ http_client_peer_connect_backoff, peer);
+ return;
+ }
+ }
+
+ http_client_peer_do_connect(peer, count);
+}
+
bool http_client_peer_is_connected(struct http_client_peer *peer)
{
struct http_client_connection *const *conn_idx;
@@ -228,7 +266,7 @@
i_assert(idle == 0);
/* determine how many new connections we can set up */
- if (peer->last_connect_failed && working_conn_count > 0 &&
+ if (peer->last_failure.tv_sec > 0 && working_conn_count > 0 &&
working_conn_count == connecting) {
/* don't create new connections until the existing ones have
finished connecting successfully. */
@@ -381,6 +419,8 @@
if (peer->to_req_handling != NULL)
timeout_remove(&peer->to_req_handling);
+ if (peer->to_backoff != NULL)
+ timeout_remove(&peer->to_backoff);
/* make a copy of the connection array; freed connections modify it */
t_array_init(&conns, array_count(&peer->conns));
@@ -471,7 +511,11 @@
{
struct http_client_queue *const *queue;
- peer->last_connect_failed = FALSE;
+ peer->last_failure.tv_sec = peer->last_failure.tv_usec = 0;
+ peer->backoff_time_msecs = 0;
+
+ if (peer->to_backoff != NULL)
+ timeout_remove(&peer->to_backoff);
array_foreach(&peer->queues, queue) {
http_client_queue_connection_success(*queue, &peer->addr);
@@ -483,6 +527,7 @@
void http_client_peer_connection_failure(struct http_client_peer *peer,
const char *reason)
{
+ const struct http_client_settings *set = &peer->client->set;
struct http_client_queue *const *queue;
unsigned int num_urgent;
@@ -490,7 +535,15 @@
http_client_peer_debug(peer, "Failed to make connection");
- peer->last_connect_failed = TRUE;
+ peer->last_failure = ioloop_timeval;
+
+ if (array_count(&peer->conns) == 1) {
+ if (peer->backoff_time_msecs == 0)
+ peer->backoff_time_msecs = set->connect_backoff_time_msecs;
+ else
+ peer->backoff_time_msecs *= 2;
+ }
+
if (array_count(&peer->conns) > 1) {
/* if there are other connections attempting to connect, wait
for them before failing the requests. remember that we had
@@ -553,5 +606,9 @@
peer->to_req_handling =
io_loop_move_timeout(&peer->to_req_handling);
}
+ if (peer->to_backoff != NULL) {
+ peer->to_backoff =
+ io_loop_move_timeout(&peer->to_backoff);
+ }
}
diff -r 650629de6a73 -r 4412508cbc59 src/lib-http/http-client-private.h
--- a/src/lib-http/http-client-private.h Wed Sep 10 13:39:37 2014 +0300
+++ b/src/lib-http/http-client-private.h Wed Sep 10 13:39:37 2014 +0300
@@ -11,8 +11,9 @@
#define HTTP_CLIENT_DNS_LOOKUP_TIMEOUT_MSECS (1000*30)
#define HTTP_CLIENT_CONNECT_TIMEOUT_MSECS (1000*30)
+#define HTTP_CLIENT_CONTINUE_TIMEOUT_MSECS (1000*2)
#define HTTP_CLIENT_DEFAULT_REQUEST_TIMEOUT_MSECS (1000*60*5)
-#define HTTP_CLIENT_CONTINUE_TIMEOUT_MSECS (1000*2)
+#define HTTP_CLIENT_DEFAULT_BACKOFF_TIME_MSECS (100)
enum http_response_payload_type;
@@ -159,10 +160,14 @@
/* zero time-out for consolidating request handling */
struct timeout *to_req_handling;
+ /* connection retry */
+ struct timeval last_failure;
+ struct timeout *to_backoff;
+ unsigned int backoff_time_msecs;
+
unsigned int destroyed:1; /* peer is being destroyed */
unsigned int no_payload_sync:1; /* expect: 100-continue failed before */
unsigned int seen_100_response:1;/* expect: 100-continue succeeded before */
- unsigned int last_connect_failed:1;
unsigned int allows_pipelining:1;/* peer is known to allow persistent
connections */
};
diff -r 650629de6a73 -r 4412508cbc59 src/lib-http/http-client.c
--- a/src/lib-http/http-client.c Wed Sep 10 13:39:37 2014 +0300
+++ b/src/lib-http/http-client.c Wed Sep 10 13:39:37 2014 +0300
@@ -121,6 +121,10 @@
(set->max_pipelined_requests > 0 ? set->max_pipelined_requests : 1);
client->set.max_attempts = set->max_attempts;
client->set.max_connect_attempts = set->max_connect_attempts;
+ client->set.connect_backoff_time_msecs =
+ set->connect_backoff_time_msecs == 0 ?
+ HTTP_CLIENT_DEFAULT_BACKOFF_TIME_MSECS :
+ set->connect_backoff_time_msecs;
client->set.no_auto_redirect = set->no_auto_redirect;
client->set.no_ssl_tunnel = set->no_ssl_tunnel;
client->set.max_redirects = set->max_redirects;
diff -r 650629de6a73 -r 4412508cbc59 src/lib-http/http-client.h
--- a/src/lib-http/http-client.h Wed Sep 10 13:39:37 2014 +0300
+++ b/src/lib-http/http-client.h Wed Sep 10 13:39:37 2014 +0300
@@ -92,6 +92,9 @@
*/
unsigned int max_connect_attempts;
+ /* Initial backoff time; doubled at each connection failure */
+ unsigned int connect_backoff_time_msecs;
+
/* response header limits */
struct http_header_limits response_hdr_limits;
More information about the dovecot-cvs
mailing list