http-client-queue.c revision ee3c2fb2ebbf6fbbf12085f36102553ecbcb1397
/* Copyright (c) 2013-2014 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "net.h"
#include "str.h"
#include "hash.h"
#include "array.h"
#include "bsearch-insert-pos.h"
#include "llist.h"
#include "ioloop.h"
#include "istream.h"
#include "ostream.h"
#include "time-util.h"
#include "dns-lookup.h"
#include "http-response-parser.h"
#include "http-client-private.h"
/*
* Logging
*/
static inline void
static inline void
const char *format, ...)
{
i_debug("http-client: queue %s: %s",
}
}
/*
* Queue
*/
static void
static struct http_client_queue *
const struct http_client_peer_addr *addr)
{
struct http_client_queue *const *queue_idx;
return queue;
}
return NULL;
}
struct http_client_queue *
const struct http_client_peer_addr *addr)
{
struct http_client_queue *queue;
char *name;
break;
break;
break;
default:
i_unreached();
}
queue->ips_connect_idx = 0;
}
return queue;
}
{
}
{
struct http_client_request **req;
/* abort all pending requests */
}
/* abort all delayed requests */
}
}
void
struct http_client_request *req)
{
struct http_client_request **req_idx;
break;
}
}
}
static bool
{
/* we'll always go through all the IPs. we don't necessarily start
connecting from the first IP, so we'll need to treat the IPs as
a ring buffer where we automatically wrap back to the first IP
when necessary. */
}
static void
{
/* no more IPs to try */
return;
}
/* if our our previous connection attempt takes longer than the
soft_connect_timeout, we start a connection attempt to the next IP in
parallel */
"starting parallel connection attempt to next IP",
/* next IP */
/* setup connection to new peer (can start new soft timeout) */
}
{
if (num_requests == 0)
return;
/* update our peer address */
if (!http_client_peer_is_connected(peer)) {
unsigned int msecs;
/* not already connected, wait for connections */
/* start soft connect time-out (but only if we have another IP left) */
queue->to_connect =
}
}
}
void
const struct http_client_peer_addr *addr)
{
/* we achieved at least one connection the the addr->ip */
/* stop soft connect time-out */
/* drop all other attempts to the hport. note that we get here whenever
a connection is successfully created, so pending_peers array
may be empty. */
struct http_client_peer *const *peer_idx;
/* don't drop any connections to the successfully
connected peer, even if some of the connections
are pending. they may be intended for urgent
requests. */
continue;
}
peer will be freed, closing all connections.
*/
}
}
}
bool
{
"(%u peers pending, %u requests pending)",
struct http_client_peer *const *peer_idx;
/* we're still doing the initial connections to this hport. if
we're also doing parallel connections with soft timeouts
(pending_peer_count>1), wait for them to finish
first. */
break;
}
}
"Waiting for remaining pending peers.");
return TRUE;
}
}
/* one of the connections failed. if we're not using soft timeouts,
we need to try to connect to the next IP. if we are using soft
timeouts, we've already tried all of the IPs by now. */
"Failed to set up any connection; failing all queued requests");
/* all IPs failed, but retry all of them again on the
next request. */
return FALSE;
}
return TRUE;
}
struct http_client_request *req)
{
else
}
static void
{
struct http_client_request *const *reqs;
finished = 0;
for (i = 0; i < count; i++) {
break;
}
"Activated delayed request %s%s",
finished++;
}
if (i < count) {
}
}
static void
{
int msecs;
/* round up to nearest microsecond */
/* set timer */
}
static int
struct http_client_request *const *req2)
{
}
struct http_client_request *req)
{
unsigned int insert_idx;
if (insert_idx == 0)
return;
}
}
}
struct http_client_request *
{
struct http_client_request *const *requests;
struct http_client_request *req;
unsigned int i, count;
if (count == 0)
return NULL;
i = 0;
if (i == count)
return NULL;
}
}
"Connection to peer %s claimed request %s %s",
return req;
}
unsigned int
unsigned int *num_urgent_r)
{
struct http_client_request *const *requests;
unsigned int count, i;
*num_urgent_r = 0;
for (i = 0; i < count; i++) {
(*num_urgent_r)++;
else
break;
}
return count;
}
{
}