host->client = client;
host->name = i_strdup(hostname);
i_array_init(&host->queues, 4);
- i_array_init(&host->delayed_failing_requests, 1);
hostname = host->name;
hash_table_insert(client->hosts, hostname, host);
{
struct http_client_host *host = *_host;
struct http_client_queue *const *queue_idx;
- struct http_client_request *req, *const *req_idx;
const char *hostname = host->name;
http_client_host_debug(host, "Host destroy");
}
array_free(&host->queues);
- while (array_count(&host->delayed_failing_requests) > 0) {
- req_idx = array_idx(&host->delayed_failing_requests, 0);
- req = *req_idx;
-
- i_assert(req->refcount == 1);
- http_client_request_error_delayed(&req);
- }
- array_free(&host->delayed_failing_requests);
-
- if (host->to_failing_requests != NULL)
- timeout_remove(&host->to_failing_requests);
-
i_free(host->ips);
i_free(host->name);
i_free(host);
}
-static void
-http_client_host_handle_request_errors(struct http_client_host *host)
-{
- timeout_remove(&host->to_failing_requests);
-
- while (array_count(&host->delayed_failing_requests) > 0) {
- struct http_client_request *const *req_idx =
- array_idx(&host->delayed_failing_requests, 0);
- struct http_client_request *req = *req_idx;
-
- i_assert(req->refcount == 1);
- http_client_request_error_delayed(&req);
- }
- array_clear(&host->delayed_failing_requests);
-}
-
-void http_client_host_delay_request_error(struct http_client_host *host,
- struct http_client_request *req)
-{
- if (host->to_failing_requests == NULL) {
- host->to_failing_requests = timeout_add_short(0,
- http_client_host_handle_request_errors, host);
- }
- array_append(&host->delayed_failing_requests, &req, 1);
-}
-
-void http_client_host_remove_request_error(struct http_client_host *host,
- struct http_client_request *req)
-{
- struct http_client_request *const *reqs;
- unsigned int i, count;
-
- reqs = array_get(&host->delayed_failing_requests, &count);
- for (i = 0; i < count; i++) {
- if (reqs[i] == req) {
- array_delete(&host->delayed_failing_requests, i, 1);
- return;
- }
- }
-}
-
void http_client_host_switch_ioloop(struct http_client_host *host)
{
struct http_client_queue *const *queue_idx;
dns_lookup_switch_ioloop(host->dns_lookup);
array_foreach(&host->queues, queue_idx)
http_client_queue_switch_ioloop(*queue_idx);
- if (host->to_failing_requests != NULL) {
- host->to_failing_requests =
- io_loop_move_timeout(&host->to_failing_requests);
- }
}
unsigned int ips_count;
struct ip_addr *ips;
- /* list of requests in this host that are waiting for ioloop */
- ARRAY(struct http_client_request *) delayed_failing_requests;
- struct timeout *to_failing_requests;
-
/* requests are managed on a per-port basis */
ARRAY_TYPE(http_client_queue) queues;
struct ioloop *ioloop;
struct ssl_iostream_context *ssl_ctx;
+ /* list of failed requests that are waiting for ioloop */
+ ARRAY(struct http_client_request *) delayed_failing_requests;
+ struct timeout *to_failing_requests;
+
struct connection_list *conn_list;
HASH_TABLE_TYPE(http_client_host) hosts;
void http_client_host_free(struct http_client_host **_host);
void http_client_host_submit_request(struct http_client_host *host,
struct http_client_request *req);
-void http_client_host_delay_request_error(struct http_client_host *host,
+void http_client_host_switch_ioloop(struct http_client_host *host);
+
+void http_client_delay_request_error(struct http_client *client,
struct http_client_request *req);
-void http_client_host_remove_request_error(struct http_client_host *host,
+void http_client_remove_request_error(struct http_client *client,
struct http_client_request *req);
-void http_client_host_switch_ioloop(struct http_client_host *host);
+
static inline const char *
http_client_peer_addr2str(const struct http_client_peer_addr *addr)
io_loop_stop(client->ioloop);
if (req->delayed_error != NULL)
- http_client_host_remove_request_error(req->host, req);
+ http_client_remove_request_error(req->client, req);
if (req->payload_input != NULL)
i_stream_unref(&req->payload_input);
if (req->payload_output != NULL)
i_assert(req->delayed_error == NULL);
req->delayed_error = p_strdup(req->pool, error);
req->delayed_error_status = status;
- http_client_host_delay_request_error(req->host, req);
+ http_client_delay_request_error(req->client, req);
} else {
http_client_request_send_error(req, status, error);
http_client_request_unref(&req);
client->set.max_auto_retry_delay = set->max_auto_retry_delay;
client->set.debug = set->debug;
+ i_array_init(&client->delayed_failing_requests, 1);
+
client->conn_list = http_client_connection_list_init();
hash_table_create(&client->hosts, default_pool, 0, str_hash, strcmp);
void http_client_deinit(struct http_client **_client)
{
struct http_client *client = *_client;
+ struct http_client_request *req, *const *req_idx;
struct http_client_host *host;
struct http_client_peer *peer;
+ /* drop delayed failing requests */
+ while (array_count(&client->delayed_failing_requests) > 0) {
+ req_idx = array_idx(&client->delayed_failing_requests, 0);
+ req = *req_idx;
+
+ i_assert(req->refcount == 1);
+ http_client_request_error_delayed(&req);
+ }
+ array_free(&client->delayed_failing_requests);
+
+ if (client->to_failing_requests != NULL)
+ timeout_remove(&client->to_failing_requests);
+
/* free peers */
while (client->peers_list != NULL) {
peer = client->peers_list;
/* move dns lookups and delayed requests */
for (host = client->hosts_list; host != NULL; host = host->next)
http_client_host_switch_ioloop(host);
+
+ /* move timeouts */
+ if (client->to_failing_requests != NULL) {
+ client->to_failing_requests =
+ io_loop_move_timeout(&client->to_failing_requests);
+ }
}
void http_client_wait(struct http_client *client)
}
return 0;
}
+
+/*
+ * Delayed request errors
+ */
+
+static void
+http_client_handle_request_errors(struct http_client *client)
+{
+ timeout_remove(&client->to_failing_requests);
+
+ while (array_count(&client->delayed_failing_requests) > 0) {
+ struct http_client_request *const *req_idx =
+ array_idx(&client->delayed_failing_requests, 0);
+ struct http_client_request *req = *req_idx;
+
+ i_assert(req->refcount == 1);
+ http_client_request_error_delayed(&req);
+ }
+ array_clear(&client->delayed_failing_requests);
+}
+
+void http_client_delay_request_error(struct http_client *client,
+ struct http_client_request *req)
+{
+ if (client->to_failing_requests == NULL) {
+ client->to_failing_requests = timeout_add_short(0,
+ http_client_handle_request_errors, client);
+ }
+ array_append(&client->delayed_failing_requests, &req, 1);
+}
+
+void http_client_remove_request_error(struct http_client *client,
+ struct http_client_request *req)
+{
+ struct http_client_request *const *reqs;
+ unsigned int i, count;
+
+ reqs = array_get(&client->delayed_failing_requests, &count);
+ for (i = 0; i < count; i++) {
+ if (reqs[i] == req) {
+ array_delete(&client->delayed_failing_requests, i, 1);
+ return;
+ }
+ }
+}