Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Copy the last required bits from rr to upstream_fair

upstream_fair is now completely independent from the round robin module
(except of course of lots of copy-pasted code).
  • Loading branch information...
commit e0e43a85e643b7eb6d2347e8ebd988144f9395a8 1 parent c9b5a00
@gnosek authored
Showing with 183 additions and 1 deletion.
  1. +183 −1 ngx_http_upstream_fair_module.c
View
184 ngx_http_upstream_fair_module.c
@@ -342,6 +342,188 @@ ngx_http_upstream_fair(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
static ngx_int_t
+ngx_http_upstream_cmp_servers(const void *one, const void *two)
+{
+ ngx_http_upstream_rr_peer_t *first, *second;
+
+ first = (ngx_http_upstream_rr_peer_t *) one;
+ second = (ngx_http_upstream_rr_peer_t *) two;
+
+ return (first->weight < second->weight);
+}
+
+
+/* TODO: Actually support backup servers */
+static ngx_int_t
+ngx_http_upstream_init_fair_rr(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us)
+{
+ ngx_url_t u;
+ ngx_uint_t i, j, n;
+ ngx_http_upstream_server_t *server;
+ ngx_http_upstream_rr_peers_t *peers, *backup;
+
+ us->peer.init = ngx_http_upstream_init_round_robin_peer;
+
+ if (us->servers) {
+ server = us->servers->elts;
+
+ n = 0;
+
+ for (i = 0; i < us->servers->nelts; i++) {
+ if (server[i].backup) {
+ continue;
+ }
+
+ n += server[i].naddrs;
+ }
+
+ peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t)
+ + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1));
+ if (peers == NULL) {
+ return NGX_ERROR;
+ }
+
+ peers->single = (n == 1);
+ peers->number = n;
+ peers->name = &us->host;
+
+ n = 0;
+
+ for (i = 0; i < us->servers->nelts; i++) {
+ for (j = 0; j < server[i].naddrs; j++) {
+ if (server[i].backup) {
+ continue;
+ }
+
+ peers->peer[n].sockaddr = server[i].addrs[j].sockaddr;
+ peers->peer[n].socklen = server[i].addrs[j].socklen;
+ peers->peer[n].name = server[i].addrs[j].name;
+ peers->peer[n].max_fails = server[i].max_fails;
+ peers->peer[n].fail_timeout = server[i].fail_timeout;
+ peers->peer[n].down = server[i].down;
+ peers->peer[n].weight = server[i].down ? 0 : server[i].weight;
+ peers->peer[n].current_weight = peers->peer[n].weight;
+ n++;
+ }
+ }
+
+ us->peer.data = peers;
+
+ ngx_sort(&peers->peer[0], (size_t) n,
+ sizeof(ngx_http_upstream_rr_peer_t),
+ ngx_http_upstream_cmp_servers);
+
+ /* backup servers */
+
+ n = 0;
+
+ for (i = 0; i < us->servers->nelts; i++) {
+ if (!server[i].backup) {
+ continue;
+ }
+
+ n += server[i].naddrs;
+ }
+
+ if (n == 0) {
+ return NGX_OK;
+ }
+
+ backup = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t)
+ + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1));
+ if (backup == NULL) {
+ return NGX_ERROR;
+ }
+
+ peers->single = 0;
+ backup->single = 0;
+ backup->number = n;
+ backup->name = &us->host;
+
+ n = 0;
+
+ for (i = 0; i < us->servers->nelts; i++) {
+ for (j = 0; j < server[i].naddrs; j++) {
+ if (!server[i].backup) {
+ continue;
+ }
+
+ backup->peer[n].sockaddr = server[i].addrs[j].sockaddr;
+ backup->peer[n].socklen = server[i].addrs[j].socklen;
+ backup->peer[n].name = server[i].addrs[j].name;
+ backup->peer[n].weight = server[i].weight;
+ backup->peer[n].current_weight = server[i].weight;
+ backup->peer[n].max_fails = server[i].max_fails;
+ backup->peer[n].fail_timeout = server[i].fail_timeout;
+ backup->peer[n].down = server[i].down;
+ n++;
+ }
+ }
+
+ peers->next = backup;
+
+ ngx_sort(&backup->peer[0], (size_t) n,
+ sizeof(ngx_http_upstream_rr_peer_t),
+ ngx_http_upstream_cmp_servers);
+
+ return NGX_OK;
+ }
+
+
+ /* an upstream implicitly defined by proxy_pass, etc. */
+
+ if (us->port == 0 && us->default_port == 0) {
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+ "no port in upstream \"%V\" in %s:%ui",
+ &us->host, us->file_name, us->line);
+ return NGX_ERROR;
+ }
+
+ ngx_memzero(&u, sizeof(ngx_url_t));
+
+ u.host = us->host;
+ u.port = (in_port_t) (us->port ? us->port : us->default_port);
+
+ if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) {
+ if (u.err) {
+ ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
+ "%s in upstream \"%V\" in %s:%ui",
+ u.err, &us->host, us->file_name, us->line);
+ }
+
+ return NGX_ERROR;
+ }
+
+ n = u.naddrs;
+
+ peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t)
+ + sizeof(ngx_http_upstream_rr_peer_t) * (n - 1));
+ if (peers == NULL) {
+ return NGX_ERROR;
+ }
+
+ peers->single = (n == 1);
+ peers->number = n;
+ peers->name = &us->host;
+
+ for (i = 0; i < u.naddrs; i++) {
+ peers->peer[i].sockaddr = u.addrs[i].sockaddr;
+ peers->peer[i].socklen = u.addrs[i].socklen;
+ peers->peer[i].name = u.addrs[i].name;
+ peers->peer[i].weight = 1;
+ peers->peer[i].current_weight = 1;
+ peers->peer[i].max_fails = 1;
+ peers->peer[i].fail_timeout = 10;
+ }
+
+ us->peer.data = peers;
+
+ /* implicitly defined upstream has no backup servers */
+
+ return NGX_OK;
+}
+
+static ngx_int_t
ngx_http_upstream_init_fair(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us)
{
ngx_http_upstream_fair_peers_t *peers;
@@ -349,7 +531,7 @@ ngx_http_upstream_init_fair(ngx_conf_t *cf, ngx_http_upstream_srv_conf_t *us)
ngx_str_t *shm_name;
/* do the dirty work using rr module */
- if (ngx_http_upstream_init_round_robin(cf, us) != NGX_OK) {
+ if (ngx_http_upstream_init_fair_rr(cf, us) != NGX_OK) {
return NGX_ERROR;
}
Please sign in to comment.
Something went wrong with that request. Please try again.