]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-http: client: Fixed behavior of connection backoff timer when multiple IPs are...
authorStephan Bosch <stephan@rename-it.nl>
Mon, 20 Oct 2014 15:54:27 +0000 (08:54 -0700)
committerStephan Bosch <stephan@rename-it.nl>
Mon, 20 Oct 2014 15:54:27 +0000 (08:54 -0700)
Peer backoff data was lost because peer was destroyed quickly. Now the peer
object is retained during the backoff period, so that new connection
attempts adhere to the backoff period.

src/lib-http/http-client-peer.c

index 8fc3b87fa5392f2fe6d0cc91896e4c5a81efccb8..c5c846c1aaad6fc0aa0b0ec00cfb7c57f612e3b0 100644 (file)
@@ -91,7 +91,6 @@ http_client_peer_do_connect(struct http_client_peer *peer,
        }
 }
 
-
 static void
 http_client_peer_connect_backoff(struct http_client_peer *peer)
 {
@@ -101,18 +100,25 @@ http_client_peer_connect_backoff(struct http_client_peer *peer)
                "Backoff timer expired");
 
        timeout_remove(&peer->to_backoff);
+
+       if (array_count(&peer->queues) == 0) {
+               http_client_peer_free(&peer);
+               return;
+       }
+
        http_client_peer_do_connect(peer, 1);
 }
 
-static void
-http_client_peer_connect(struct http_client_peer *peer, unsigned int count)
+static bool
+http_client_peer_start_backoff_timer(struct http_client_peer *peer)
 {
        if (peer->to_backoff != NULL)
-               return;
+               return TRUE;
 
        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",
@@ -120,9 +126,21 @@ http_client_peer_connect(struct http_client_peer *peer, unsigned int count)
                        peer->to_backoff = timeout_add
                                ((unsigned int)(peer->backoff_time_msecs - backoff_time_spent),
                                        http_client_peer_connect_backoff, peer);
-                       return;
+                       return TRUE;
                }
+
+               http_client_peer_debug(peer,
+                       "Backoff time already exceeded by %d msecs",
+                       backoff_time_spent - peer->backoff_time_msecs);
        }
+       return FALSE;
+}
+
+static void
+http_client_peer_connect(struct http_client_peer *peer, unsigned int count)
+{
+       if (http_client_peer_start_backoff_timer(peer))
+               return;
 
        http_client_peer_do_connect(peer, count);
 }
@@ -483,8 +501,10 @@ void http_client_peer_unlink_queue(struct http_client_peer *peer,
                if (*queue_idx == queue) {
                        array_delete(&peer->queues,
                                array_foreach_idx(&peer->queues, queue_idx), 1);
-                       if (array_count(&peer->queues) == 0)
-                               http_client_peer_free(&peer);
+                       if (array_count(&peer->queues) == 0) {
+                               if (!http_client_peer_start_backoff_timer(peer))
+                                       http_client_peer_free(&peer);
+                       }
                        return;
                }
        }
@@ -511,6 +531,10 @@ void http_client_peer_connection_success(struct http_client_peer *peer)
 {
        struct http_client_queue *const *queue;
 
+       http_client_peer_debug(peer,
+               "Successfully connected (connections=%u)",
+               array_count(&peer->conns));
+
        peer->last_failure.tv_sec = peer->last_failure.tv_usec = 0;
        peer->backoff_time_msecs = 0;