~ubuntu-branches/ubuntu/trusty/nginx/trusty-proposed

« back to all changes in this revision

Viewing changes to src/http/ngx_http_upstream_round_robin.c

  • Committer: Package Import Robot
  • Author(s): Kartik Mistry
  • Date: 2013-04-25 12:51:45 UTC
  • mfrom: (1.3.28)
  • mto: (1.3.29) (15.1.2 experimental)
  • mto: This revision was merged to the branch mainline in revision 64.
  • Revision ID: package-import@ubuntu.com-20130425125145-ugl0wor6bq0u5eae
Tags: upstream-1.4.0
ImportĀ upstreamĀ versionĀ 1.4.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
 
2
2
/*
3
3
 * Copyright (C) Igor Sysoev
 
4
 * Copyright (C) Nginx, Inc.
4
5
 */
5
6
 
6
7
 
9
10
#include <ngx_http.h>
10
11
 
11
12
 
12
 
static ngx_int_t ngx_http_upstream_cmp_servers(const void *one,
13
 
    const void *two);
14
 
static ngx_uint_t
15
 
ngx_http_upstream_get_peer(ngx_http_upstream_rr_peers_t *peers);
 
13
static ngx_http_upstream_rr_peer_t *ngx_http_upstream_get_peer(
 
14
    ngx_http_upstream_rr_peer_data_t *rrp);
 
15
 
 
16
#if (NGX_HTTP_SSL)
 
17
 
 
18
static ngx_int_t ngx_http_upstream_empty_set_session(ngx_peer_connection_t *pc,
 
19
    void *data);
 
20
static void ngx_http_upstream_empty_save_session(ngx_peer_connection_t *pc,
 
21
    void *data);
 
22
 
 
23
#endif
16
24
 
17
25
 
18
26
ngx_int_t
20
28
    ngx_http_upstream_srv_conf_t *us)
21
29
{
22
30
    ngx_url_t                      u;
23
 
    ngx_uint_t                     i, j, n;
 
31
    ngx_uint_t                     i, j, n, w;
24
32
    ngx_http_upstream_server_t    *server;
25
33
    ngx_http_upstream_rr_peers_t  *peers, *backup;
26
34
 
30
38
        server = us->servers->elts;
31
39
 
32
40
        n = 0;
 
41
        w = 0;
33
42
 
34
43
        for (i = 0; i < us->servers->nelts; i++) {
35
44
            if (server[i].backup) {
37
46
            }
38
47
 
39
48
            n += server[i].naddrs;
 
49
            w += server[i].naddrs * server[i].weight;
 
50
        }
 
51
 
 
52
        if (n == 0) {
 
53
            ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
 
54
                          "no servers in upstream \"%V\" in %s:%ui",
 
55
                          &us->host, us->file_name, us->line);
 
56
            return NGX_ERROR;
40
57
        }
41
58
 
42
59
        peers = ngx_pcalloc(cf->pool, sizeof(ngx_http_upstream_rr_peers_t)
47
64
 
48
65
        peers->single = (n == 1);
49
66
        peers->number = n;
 
67
        peers->weighted = (w != n);
 
68
        peers->total_weight = w;
50
69
        peers->name = &us->host;
51
70
 
52
71
        n = 0;
63
82
                peers->peer[n].max_fails = server[i].max_fails;
64
83
                peers->peer[n].fail_timeout = server[i].fail_timeout;
65
84
                peers->peer[n].down = server[i].down;
66
 
                peers->peer[n].weight = server[i].down ? 0 : server[i].weight;
67
 
                peers->peer[n].current_weight = peers->peer[n].weight;
 
85
                peers->peer[n].weight = server[i].weight;
 
86
                peers->peer[n].effective_weight = server[i].weight;
 
87
                peers->peer[n].current_weight = 0;
68
88
                n++;
69
89
            }
70
90
        }
71
91
 
72
92
        us->peer.data = peers;
73
93
 
74
 
        ngx_sort(&peers->peer[0], (size_t) n,
75
 
                 sizeof(ngx_http_upstream_rr_peer_t),
76
 
                 ngx_http_upstream_cmp_servers);
77
 
 
78
94
        /* backup servers */
79
95
 
80
96
        n = 0;
 
97
        w = 0;
81
98
 
82
99
        for (i = 0; i < us->servers->nelts; i++) {
83
100
            if (!server[i].backup) {
85
102
            }
86
103
 
87
104
            n += server[i].naddrs;
 
105
            w += server[i].naddrs * server[i].weight;
88
106
        }
89
107
 
90
108
        if (n == 0) {
100
118
        peers->single = 0;
101
119
        backup->single = 0;
102
120
        backup->number = n;
 
121
        backup->weighted = (w != n);
 
122
        backup->total_weight = w;
103
123
        backup->name = &us->host;
104
124
 
105
125
        n = 0;
114
134
                backup->peer[n].socklen = server[i].addrs[j].socklen;
115
135
                backup->peer[n].name = server[i].addrs[j].name;
116
136
                backup->peer[n].weight = server[i].weight;
117
 
                backup->peer[n].current_weight = server[i].weight;
 
137
                backup->peer[n].effective_weight = server[i].weight;
 
138
                backup->peer[n].current_weight = 0;
118
139
                backup->peer[n].max_fails = server[i].max_fails;
119
140
                backup->peer[n].fail_timeout = server[i].fail_timeout;
120
141
                backup->peer[n].down = server[i].down;
124
145
 
125
146
        peers->next = backup;
126
147
 
127
 
        ngx_sort(&backup->peer[0], (size_t) n,
128
 
                 sizeof(ngx_http_upstream_rr_peer_t),
129
 
                 ngx_http_upstream_cmp_servers);
130
 
 
131
148
        return NGX_OK;
132
149
    }
133
150
 
134
151
 
135
152
    /* an upstream implicitly defined by proxy_pass, etc. */
136
153
 
137
 
    if (us->port == 0 && us->default_port == 0) {
 
154
    if (us->port == 0) {
138
155
        ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
139
156
                      "no port in upstream \"%V\" in %s:%ui",
140
157
                      &us->host, us->file_name, us->line);
144
161
    ngx_memzero(&u, sizeof(ngx_url_t));
145
162
 
146
163
    u.host = us->host;
147
 
    u.port = (in_port_t) (us->port ? us->port : us->default_port);
 
164
    u.port = us->port;
148
165
 
149
166
    if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) {
150
167
        if (u.err) {
166
183
 
167
184
    peers->single = (n == 1);
168
185
    peers->number = n;
 
186
    peers->weighted = 0;
 
187
    peers->total_weight = n;
169
188
    peers->name = &us->host;
170
189
 
171
190
    for (i = 0; i < u.naddrs; i++) {
173
192
        peers->peer[i].socklen = u.addrs[i].socklen;
174
193
        peers->peer[i].name = u.addrs[i].name;
175
194
        peers->peer[i].weight = 1;
176
 
        peers->peer[i].current_weight = 1;
 
195
        peers->peer[i].effective_weight = 1;
 
196
        peers->peer[i].current_weight = 0;
177
197
        peers->peer[i].max_fails = 1;
178
198
        peers->peer[i].fail_timeout = 10;
179
199
    }
186
206
}
187
207
 
188
208
 
189
 
static ngx_int_t
190
 
ngx_http_upstream_cmp_servers(const void *one, const void *two)
191
 
{
192
 
    ngx_http_upstream_rr_peer_t  *first, *second;
193
 
 
194
 
    first = (ngx_http_upstream_rr_peer_t *) one;
195
 
    second = (ngx_http_upstream_rr_peer_t *) two;
196
 
 
197
 
    return (first->weight < second->weight);
198
 
}
199
 
 
200
 
 
201
209
ngx_int_t
202
210
ngx_http_upstream_init_round_robin_peer(ngx_http_request_t *r,
203
211
    ngx_http_upstream_srv_conf_t *us)
219
227
    rrp->peers = us->peer.data;
220
228
    rrp->current = 0;
221
229
 
222
 
    if (rrp->peers->number <= 8 * sizeof(uintptr_t)) {
 
230
    n = rrp->peers->number;
 
231
 
 
232
    if (rrp->peers->next && rrp->peers->next->number > n) {
 
233
        n = rrp->peers->next->number;
 
234
    }
 
235
 
 
236
    if (n <= 8 * sizeof(uintptr_t)) {
223
237
        rrp->tried = &rrp->data;
224
238
        rrp->data = 0;
225
239
 
226
240
    } else {
227
 
        n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1))
228
 
                / (8 * sizeof(uintptr_t));
 
241
        n = (n + (8 * sizeof(uintptr_t) - 1)) / (8 * sizeof(uintptr_t));
229
242
 
230
243
        rrp->tried = ngx_pcalloc(r->pool, n * sizeof(uintptr_t));
231
244
        if (rrp->tried == NULL) {
279
292
    peers->number = ur->naddrs;
280
293
    peers->name = &ur->host;
281
294
 
282
 
    for (i = 0; i < ur->naddrs; i++) {
283
 
 
284
 
        len = INET_ADDRSTRLEN - 1 + 1 + sizeof(":65536") - 1;
285
 
 
286
 
        p = ngx_palloc(r->pool, len);
287
 
        if (p == NULL) {
288
 
            return NGX_ERROR;
289
 
        }
290
 
 
291
 
        len = ngx_inet_ntop(AF_INET, &ur->addrs[i], p, INET_ADDRSTRLEN);
292
 
        len = ngx_sprintf(&p[len], ":%d", ur->port) - p;
293
 
 
294
 
        sin = ngx_pcalloc(r->pool, sizeof(struct sockaddr_in));
295
 
        if (sin == NULL) {
296
 
            return NGX_ERROR;
297
 
        }
298
 
 
299
 
        sin->sin_family = AF_INET;
300
 
        sin->sin_port = htons(ur->port);
301
 
        sin->sin_addr.s_addr = ur->addrs[i];
302
 
 
303
 
        peers->peer[i].sockaddr = (struct sockaddr *) sin;
304
 
        peers->peer[i].socklen = sizeof(struct sockaddr_in);
305
 
        peers->peer[i].name.len = len;
306
 
        peers->peer[i].name.data = p;
307
 
        peers->peer[i].weight = 1;
308
 
        peers->peer[i].current_weight = 1;
309
 
        peers->peer[i].max_fails = 1;
310
 
        peers->peer[i].fail_timeout = 10;
 
295
    if (ur->sockaddr) {
 
296
        peers->peer[0].sockaddr = ur->sockaddr;
 
297
        peers->peer[0].socklen = ur->socklen;
 
298
        peers->peer[0].name = ur->host;
 
299
        peers->peer[0].weight = 1;
 
300
        peers->peer[0].effective_weight = 1;
 
301
        peers->peer[0].current_weight = 0;
 
302
        peers->peer[0].max_fails = 1;
 
303
        peers->peer[0].fail_timeout = 10;
 
304
 
 
305
    } else {
 
306
 
 
307
        for (i = 0; i < ur->naddrs; i++) {
 
308
 
 
309
            len = NGX_INET_ADDRSTRLEN + sizeof(":65536") - 1;
 
310
 
 
311
            p = ngx_pnalloc(r->pool, len);
 
312
            if (p == NULL) {
 
313
                return NGX_ERROR;
 
314
            }
 
315
 
 
316
            len = ngx_inet_ntop(AF_INET, &ur->addrs[i], p, NGX_INET_ADDRSTRLEN);
 
317
            len = ngx_sprintf(&p[len], ":%d", ur->port) - p;
 
318
 
 
319
            sin = ngx_pcalloc(r->pool, sizeof(struct sockaddr_in));
 
320
            if (sin == NULL) {
 
321
                return NGX_ERROR;
 
322
            }
 
323
 
 
324
            sin->sin_family = AF_INET;
 
325
            sin->sin_port = htons(ur->port);
 
326
            sin->sin_addr.s_addr = ur->addrs[i];
 
327
 
 
328
            peers->peer[i].sockaddr = (struct sockaddr *) sin;
 
329
            peers->peer[i].socklen = sizeof(struct sockaddr_in);
 
330
            peers->peer[i].name.len = len;
 
331
            peers->peer[i].name.data = p;
 
332
            peers->peer[i].weight = 1;
 
333
            peers->peer[i].effective_weight = 1;
 
334
            peers->peer[i].current_weight = 0;
 
335
            peers->peer[i].max_fails = 1;
 
336
            peers->peer[i].fail_timeout = 10;
 
337
        }
311
338
    }
312
339
 
313
340
    rrp->peers = peers;
331
358
    r->upstream->peer.free = ngx_http_upstream_free_round_robin_peer;
332
359
    r->upstream->peer.tries = rrp->peers->number;
333
360
#if (NGX_HTTP_SSL)
334
 
    r->upstream->peer.set_session =
335
 
                               ngx_http_upstream_set_round_robin_peer_session;
336
 
    r->upstream->peer.save_session =
337
 
                               ngx_http_upstream_save_round_robin_peer_session;
 
361
    r->upstream->peer.set_session = ngx_http_upstream_empty_set_session;
 
362
    r->upstream->peer.save_session = ngx_http_upstream_empty_save_session;
338
363
#endif
339
364
 
340
365
    return NGX_OK;
346
371
{
347
372
    ngx_http_upstream_rr_peer_data_t  *rrp = data;
348
373
 
349
 
    time_t                         now;
350
 
    uintptr_t                      m;
351
374
    ngx_int_t                      rc;
352
375
    ngx_uint_t                     i, n;
353
 
    ngx_connection_t              *c;
354
376
    ngx_http_upstream_rr_peer_t   *peer;
355
377
    ngx_http_upstream_rr_peers_t  *peers;
356
378
 
357
379
    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0,
358
380
                   "get rr peer, try: %ui", pc->tries);
359
381
 
360
 
    now = ngx_time();
361
 
 
362
382
    /* ngx_lock_mutex(rrp->peers->mutex); */
363
383
 
364
 
    if (rrp->peers->last_cached) {
365
 
 
366
 
        /* cached connection */
367
 
 
368
 
        c = rrp->peers->cached[rrp->peers->last_cached];
369
 
        rrp->peers->last_cached--;
370
 
 
371
 
        /* ngx_unlock_mutex(ppr->peers->mutex); */
372
 
 
373
 
#if (NGX_THREADS)
374
 
        c->read->lock = c->read->own_lock;
375
 
        c->write->lock = c->write->own_lock;
376
 
#endif
377
 
 
378
 
        pc->connection = c;
379
 
        pc->cached = 1;
380
 
 
381
 
        return NGX_OK;
382
 
    }
383
 
 
384
384
    pc->cached = 0;
385
385
    pc->connection = NULL;
386
386
 
387
387
    if (rrp->peers->single) {
388
388
        peer = &rrp->peers->peer[0];
389
389
 
 
390
        if (peer->down) {
 
391
            goto failed;
 
392
        }
 
393
 
390
394
    } else {
391
395
 
392
396
        /* there are several peers */
393
397
 
394
 
        if (pc->tries == rrp->peers->number) {
395
 
 
396
 
            /* it's a first try - get a current peer */
397
 
 
398
 
            i = pc->tries;
399
 
 
400
 
            for ( ;; ) {
401
 
                rrp->current = ngx_http_upstream_get_peer(rrp->peers);
402
 
 
403
 
                ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
404
 
                               "get rr peer, current: %ui %i",
405
 
                               rrp->current,
406
 
                               rrp->peers->peer[rrp->current].current_weight);
407
 
 
408
 
                n = rrp->current / (8 * sizeof(uintptr_t));
409
 
                m = (uintptr_t) 1 << rrp->current % (8 * sizeof(uintptr_t));
410
 
 
411
 
                if (!(rrp->tried[n] & m)) {
412
 
                    peer = &rrp->peers->peer[rrp->current];
413
 
 
414
 
                    if (!peer->down) {
415
 
 
416
 
                        if (peer->max_fails == 0
417
 
                            || peer->fails < peer->max_fails)
418
 
                        {
419
 
                            break;
420
 
                        }
421
 
 
422
 
                        if (now - peer->accessed > peer->fail_timeout) {
423
 
                            peer->fails = 0;
424
 
                            break;
425
 
                        }
426
 
 
427
 
                        peer->current_weight = 0;
428
 
 
429
 
                    } else {
430
 
                        rrp->tried[n] |= m;
431
 
                    }
432
 
 
433
 
                    pc->tries--;
434
 
                }
435
 
 
436
 
                if (pc->tries == 0) {
437
 
                    goto failed;
438
 
                }
439
 
 
440
 
                if (--i == 0) {
441
 
                    ngx_log_error(NGX_LOG_ALERT, pc->log, 0,
442
 
                                  "round robin upstream stuck on %ui tries",
443
 
                                  pc->tries);
444
 
                    goto failed;
445
 
                }
446
 
            }
447
 
 
448
 
            peer->current_weight--;
449
 
 
450
 
        } else {
451
 
 
452
 
            i = pc->tries;
453
 
 
454
 
            for ( ;; ) {
455
 
                n = rrp->current / (8 * sizeof(uintptr_t));
456
 
                m = (uintptr_t) 1 << rrp->current % (8 * sizeof(uintptr_t));
457
 
 
458
 
                if (!(rrp->tried[n] & m)) {
459
 
 
460
 
                    peer = &rrp->peers->peer[rrp->current];
461
 
 
462
 
                    if (!peer->down) {
463
 
 
464
 
                        if (peer->max_fails == 0
465
 
                            || peer->fails < peer->max_fails)
466
 
                        {
467
 
                            break;
468
 
                        }
469
 
 
470
 
                        if (now - peer->accessed > peer->fail_timeout) {
471
 
                            peer->fails = 0;
472
 
                            break;
473
 
                        }
474
 
 
475
 
                        peer->current_weight = 0;
476
 
 
477
 
                    } else {
478
 
                        rrp->tried[n] |= m;
479
 
                    }
480
 
 
481
 
                    pc->tries--;
482
 
                }
483
 
 
484
 
                rrp->current++;
485
 
 
486
 
                if (rrp->current >= rrp->peers->number) {
487
 
                    rrp->current = 0;
488
 
                }
489
 
 
490
 
                if (pc->tries == 0) {
491
 
                    goto failed;
492
 
                }
493
 
 
494
 
                if (--i == 0) {
495
 
                    ngx_log_error(NGX_LOG_ALERT, pc->log, 0,
496
 
                                  "round robin upstream stuck on %ui tries",
497
 
                                  pc->tries);
498
 
                    goto failed;
499
 
                }
500
 
            }
501
 
 
502
 
            peer->current_weight--;
 
398
        peer = ngx_http_upstream_get_peer(rrp);
 
399
 
 
400
        if (peer == NULL) {
 
401
            goto failed;
503
402
        }
504
403
 
505
 
        rrp->tried[n] |= m;
 
404
        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
 
405
                       "get rr peer, current: %ui %i",
 
406
                       rrp->current, peer->current_weight);
506
407
    }
507
408
 
508
409
    pc->sockaddr = peer->sockaddr;
513
414
 
514
415
    if (pc->tries == 1 && rrp->peers->next) {
515
416
        pc->tries += rrp->peers->next->number;
516
 
 
517
 
        n = rrp->peers->next->number / (8 * sizeof(uintptr_t)) + 1;
518
 
        for (i = 0; i < n; i++) {
519
 
             rrp->tried[i] = 0;
520
 
        }
521
417
    }
522
418
 
523
419
    return NGX_OK;
535
431
        rrp->peers = peers->next;
536
432
        pc->tries = rrp->peers->number;
537
433
 
538
 
        n = rrp->peers->number / (8 * sizeof(uintptr_t)) + 1;
 
434
        n = (rrp->peers->number + (8 * sizeof(uintptr_t) - 1))
 
435
                / (8 * sizeof(uintptr_t));
 
436
 
539
437
        for (i = 0; i < n; i++) {
540
438
             rrp->tried[i] = 0;
541
439
        }
563
461
}
564
462
 
565
463
 
566
 
static ngx_uint_t
567
 
ngx_http_upstream_get_peer(ngx_http_upstream_rr_peers_t *peers)
 
464
static ngx_http_upstream_rr_peer_t *
 
465
ngx_http_upstream_get_peer(ngx_http_upstream_rr_peer_data_t *rrp)
568
466
{
 
467
    time_t                        now;
 
468
    uintptr_t                     m;
 
469
    ngx_int_t                     total;
569
470
    ngx_uint_t                    i, n;
570
 
    ngx_http_upstream_rr_peer_t  *peer;
571
 
 
572
 
    peer = &peers->peer[0];
573
 
 
574
 
    for ( ;; ) {
575
 
 
576
 
        for (i = 0; i < peers->number; i++) {
577
 
 
578
 
            if (peer[i].current_weight <= 0) {
579
 
                continue;
580
 
            }
581
 
 
582
 
            n = i;
583
 
 
584
 
            while (i < peers->number - 1) {
585
 
 
586
 
                i++;
587
 
 
588
 
                if (peer[i].current_weight <= 0) {
589
 
                    continue;
590
 
                }
591
 
 
592
 
                if (peer[n].current_weight * 1000 / peer[i].current_weight
593
 
                    > peer[n].weight * 1000 / peer[i].weight)
594
 
                {
595
 
                    return n;
596
 
                }
597
 
 
598
 
                n = i;
599
 
            }
600
 
 
601
 
            if (peer[i].current_weight > 0) {
602
 
                n = i;
603
 
            }
604
 
 
605
 
            return n;
606
 
        }
607
 
 
608
 
        for (i = 0; i < peers->number; i++) {
609
 
            peer[i].current_weight = peer[i].weight;
610
 
        }
611
 
    }
 
471
    ngx_http_upstream_rr_peer_t  *peer, *best;
 
472
 
 
473
    now = ngx_time();
 
474
 
 
475
    best = NULL;
 
476
    total = 0;
 
477
 
 
478
    for (i = 0; i < rrp->peers->number; i++) {
 
479
 
 
480
        n = i / (8 * sizeof(uintptr_t));
 
481
        m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t));
 
482
 
 
483
        if (rrp->tried[n] & m) {
 
484
            continue;
 
485
        }
 
486
 
 
487
        peer = &rrp->peers->peer[i];
 
488
 
 
489
        if (peer->down) {
 
490
            continue;
 
491
        }
 
492
 
 
493
        if (peer->max_fails
 
494
            && peer->fails >= peer->max_fails
 
495
            && now - peer->checked <= peer->fail_timeout)
 
496
        {
 
497
            continue;
 
498
        }
 
499
 
 
500
        peer->current_weight += peer->effective_weight;
 
501
        total += peer->effective_weight;
 
502
 
 
503
        if (peer->effective_weight < peer->weight) {
 
504
            peer->effective_weight++;
 
505
        }
 
506
 
 
507
        if (best == NULL || peer->current_weight > best->current_weight) {
 
508
            best = peer;
 
509
        }
 
510
    }
 
511
 
 
512
    if (best == NULL) {
 
513
        return NULL;
 
514
    }
 
515
 
 
516
    i = best - &rrp->peers->peer[0];
 
517
 
 
518
    rrp->current = i;
 
519
 
 
520
    n = i / (8 * sizeof(uintptr_t));
 
521
    m = (uintptr_t) 1 << i % (8 * sizeof(uintptr_t));
 
522
 
 
523
    rrp->tried[n] |= m;
 
524
 
 
525
    best->current_weight -= total;
 
526
    best->checked = now;
 
527
 
 
528
    return best;
612
529
}
613
530
 
614
531
 
624
541
    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
625
542
                   "free rr peer %ui %ui", pc->tries, state);
626
543
 
627
 
    if (state == 0 && pc->tries == 0) {
628
 
        return;
629
 
    }
630
 
 
631
544
    /* TODO: NGX_PEER_KEEPALIVE */
632
545
 
633
546
    if (rrp->peers->single) {
635
548
        return;
636
549
    }
637
550
 
 
551
    peer = &rrp->peers->peer[rrp->current];
 
552
 
638
553
    if (state & NGX_PEER_FAILED) {
639
554
        now = ngx_time();
640
555
 
641
 
        peer = &rrp->peers->peer[rrp->current];
642
 
 
643
556
        /* ngx_lock_mutex(rrp->peers->mutex); */
644
557
 
645
558
        peer->fails++;
646
559
        peer->accessed = now;
 
560
        peer->checked = now;
647
561
 
648
562
        if (peer->max_fails) {
649
 
            peer->current_weight -= peer->weight / peer->max_fails;
 
563
            peer->effective_weight -= peer->weight / peer->max_fails;
650
564
        }
651
565
 
652
566
        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0,
653
567
                       "free rr peer failed: %ui %i",
654
 
                       rrp->current, peer->current_weight);
 
568
                       rrp->current, peer->effective_weight);
655
569
 
656
 
        if (peer->current_weight < 0) {
657
 
            peer->current_weight = 0;
 
570
        if (peer->effective_weight < 0) {
 
571
            peer->effective_weight = 0;
658
572
        }
659
573
 
660
574
        /* ngx_unlock_mutex(rrp->peers->mutex); */
661
 
    }
662
 
 
663
 
    rrp->current++;
664
 
 
665
 
    if (rrp->current >= rrp->peers->number) {
666
 
        rrp->current = 0;
 
575
 
 
576
    } else {
 
577
 
 
578
        /* mark peer live if check passed */
 
579
 
 
580
        if (peer->accessed < peer->checked) {
 
581
            peer->fails = 0;
 
582
        }
667
583
    }
668
584
 
669
585
    if (pc->tries) {
745
661
    }
746
662
}
747
663
 
 
664
 
 
665
static ngx_int_t
 
666
ngx_http_upstream_empty_set_session(ngx_peer_connection_t *pc, void *data)
 
667
{
 
668
    return NGX_OK;
 
669
}
 
670
 
 
671
 
 
672
static void
 
673
ngx_http_upstream_empty_save_session(ngx_peer_connection_t *pc, void *data)
 
674
{
 
675
    return;
 
676
}
 
677
 
748
678
#endif