/* This function takes the oldest request on the queue * (maxconn_cf->waiting_requests) and dispatches it to the backends. This * calls ngx_http_upstream_connect() which will in turn call the peer get * callback, peer_get(). peer_get() will do * the actual selection of backend. Here we're just giving the request the * go-ahead to proceed. */ static void dispatch (max_connections_srv_conf_t *maxconn_cf) { if (ngx_queue_empty(&maxconn_cf->waiting_requests)) return; if (maxconn_cf->connections >= maxconn_cf->max_connections) return; max_connections_peer_data_t *peer_data = queue_shift(maxconn_cf); ngx_http_request_t *r = peer_data->r; ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "max_connections dispatch (queue_length: %ui, conn: %ui)", maxconn_cf->queue_length, maxconn_cf->connections); peer_data->processing = 1; maxconn_cf->connections++; /* keep track of how many slots are occupied */ ngx_http_upstream_connect(r, r->upstream); }
static void ngx_http_upstream_dynamic_handler(ngx_resolver_ctx_t *ctx) { ngx_http_request_t *r; ngx_http_upstream_t *u; ngx_peer_connection_t *pc; struct sockaddr_in *sin, *csin; in_port_t port; ngx_str_t *addr; u_char *p; size_t len; ngx_http_upstream_srv_conf_t *us; ngx_http_upstream_dynamic_srv_conf_t *dscf; r = ctx->data; u = r->upstream; us = u->conf->upstream; pc = &u->peer; dscf = ngx_http_conf_upstream_srv_conf(us, ngx_http_upstream_dynamic_module); if (ctx->state) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "%V could not be resolved (%i: %s)", &ctx->name, ctx->state, ngx_resolver_strerror(ctx->state)); dscf->fail_check = ngx_time(); pc->resolved = NGX_HTTP_UPSTREAM_DR_FAILED; } else { /* dns query ok */ dscf->fail_check = 0; sin = ngx_pcalloc(r->pool, sizeof(struct sockaddr_in)); if (sin == NULL) { ngx_http_upstream_finalize_request(r, u, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } ngx_memcpy(sin, pc->sockaddr, pc->socklen); /* only the first IP addr is used in version 1 */ csin = (struct sockaddr_in *) ctx->addrs[0].sockaddr; if (sin->sin_addr.s_addr == csin->sin_addr.s_addr) { pc->resolved = NGX_HTTP_UPSTREAM_DR_OK; goto out; } sin->sin_addr.s_addr = csin->sin_addr.s_addr; len = NGX_INET_ADDRSTRLEN + sizeof(":65535") - 1; p = ngx_pnalloc(r->pool, len); if (p == NULL) { ngx_http_upstream_finalize_request(r, u, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } port = ntohs(sin->sin_port); len = ngx_inet_ntop(AF_INET, &sin->sin_addr.s_addr, p, NGX_INET_ADDRSTRLEN); len = ngx_sprintf(&p[len], ":%d", port) - p; addr = ngx_palloc(r->pool, sizeof(ngx_str_t)); if (addr == NULL) { ngx_http_upstream_finalize_request(r, u, NGX_HTTP_INTERNAL_SERVER_ERROR); return; } addr->data = p; addr->len = len; pc->sockaddr = (struct sockaddr *) sin; pc->socklen = sizeof(struct sockaddr_in); pc->name = addr; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "name was resolved to %V", pc->name); pc->resolved = NGX_HTTP_UPSTREAM_DR_OK; } out: ngx_resolve_name_done(ctx); u->dyn_resolve_ctx = NULL; ngx_http_upstream_connect(r, u); }