/* retry implementation is PECL memcache compatible */ static void ngx_http_upstream_free_hash_peer(ngx_peer_connection_t *pc, void *data, ngx_uint_t state) { ngx_http_upstream_hash_peer_data_t *uhpd = data; ngx_uint_t current; ngx_log_debug1(NGX_LOG_DEBUG_HTTP, pc->log, 0, "upstream_hash: free upstream hash peer try %ui", pc->tries); if (state & (NGX_PEER_FAILED|NGX_PEER_NEXT) && pc->tries) { current = uhpd->hash % uhpd->peers->number; uhpd->tried[ngx_bitvector_index(current)] |= ngx_bitvector_bit(current); ngx_http_upstream_hash_next_peer(uhpd, &pc->tries, pc->log); ngx_log_debug2(NGX_LOG_DEBUG_HTTP, pc->log, 0, "upstream_hash: Using %ui because %ui failed", uhpd->hash % uhpd->peers->number, current); } else { pc->tries = 0; } }
static void ngx_http_upstream_hash_next_peer(ngx_http_upstream_hash_peer_data_t *uhpd, ngx_uint_t *tries, ngx_log_t *log) { ngx_uint_t current; current = ngx_http_upstream_get_hash_peer_index(uhpd); // Loop while there is a try left, we're on one we haven't tried, and // the current peer isn't marked down while ((*tries)-- && ( (uhpd->tried[ngx_bitvector_index(current)] & ngx_bitvector_bit(current)) || uhpd->peers->peer[current].down #if (NGX_HTTP_HEALTHCHECK) || ngx_http_healthcheck_is_down(uhpd->peers->peer[current].health_index, log) #endif )) { uhpd->current_key.len = ngx_sprintf(uhpd->current_key.data, "%d%V", ++uhpd->try_i, &uhpd->original_key) - uhpd->current_key.data; uhpd->hash += ngx_http_upstream_hash_crc32(uhpd->current_key.data, uhpd->current_key.len); current = ngx_http_upstream_get_hash_peer_index(uhpd); ngx_log_debug2(NGX_LOG_DEBUG_HTTP, log, 0, "upstream_hash: hashed \"%V\" to %ui", &uhpd->current_key, current); } }