// destroy a peer void uwsgi_cr_peer_del(struct corerouter_peer *peer) { struct corerouter_peer *prev = peer->prev; struct corerouter_peer *next = peer->next; if (prev) { prev->next = peer->next; } if (next) { next->prev = peer->prev; } if (peer == peer->session->peers) { peer->session->peers = peer->next; } uwsgi_cr_peer_reset(peer); if (peer->in) { uwsgi_buffer_destroy(peer->in); } // main_peer bring the output buffer from backend peers if (peer->out && peer->out_need_free) { uwsgi_buffer_destroy(peer->out); } free(peer); }
// destroy a peer int uwsgi_cr_peer_del(struct corerouter_peer *peer) { // first of all check if we need to run a flush procedure if (peer->flush && !peer->is_flushing) { peer->is_flushing = 1; // on success, suspend the execution if (peer->flush(peer) > 0) return -1; } struct corerouter_peer *prev = peer->prev; struct corerouter_peer *next = peer->next; if (prev) { prev->next = peer->next; } if (next) { next->prev = peer->prev; } if (peer == peer->session->peers) { peer->session->peers = peer->next; } uwsgi_cr_peer_reset(peer); if (peer->in) { uwsgi_buffer_destroy(peer->in); } // main_peer bring the output buffer from backend peers if (peer->out && peer->out_need_free) { uwsgi_buffer_destroy(peer->out); } free(peer); return 0; }
void corerouter_close_peer(struct uwsgi_corerouter *ucr, struct corerouter_peer *peer) { struct corerouter_session *cs = peer->session; // manage subscription reference count if (ucr->subscriptions && peer->un && peer->un->len > 0) { // decrease reference count #ifdef UWSGI_DEBUG uwsgi_log("[1] node %.*s refcnt: %llu\n", peer->un->len, peer->un->name, peer->un->reference); #endif peer->un->reference--; #ifdef UWSGI_DEBUG uwsgi_log("[2] node %.*s refcnt: %llu\n", peer->un->len, peer->un->name, peer->un->reference); #endif } if (peer->failed) { if (peer->soopt) { if (!ucr->quiet) uwsgi_log("[uwsgi-%s] unable to connect() to node \"%.*s\" (%d retries): %s\n", ucr->short_name, (int) peer->instance_address_len, peer->instance_address, peer->retries, strerror(peer->soopt)); } else if (peer->timed_out) { if (peer->instance_address_len > 0) { if (peer->connecting) { if (!ucr->quiet) uwsgi_log("[uwsgi-%s] unable to connect() to node \"%.*s\" (%d retries): timeout\n", ucr->short_name, (int) peer->instance_address_len, peer->instance_address, peer->retries); } } } // now check for dead nodes if (ucr->subscriptions && peer->un && peer->un->len > 0) { if (peer->un->death_mark == 0) uwsgi_log("[uwsgi-%s] %.*s => marking %.*s as failed\n", ucr->short_name, (int) peer->key_len, peer->key, (int) peer->instance_address_len, peer->instance_address); peer->un->failcnt++; peer->un->death_mark = 1; // check if i can remove the node if (peer->un->reference == 0) { uwsgi_remove_subscribe_node(ucr->subscriptions, peer->un); } if (ucr->cheap && !ucr->i_am_cheap && !ucr->fallback && uwsgi_no_subscriptions(ucr->subscriptions)) { uwsgi_gateway_go_cheap(ucr->name, ucr->queue, &ucr->i_am_cheap); } } else if (peer->static_node) { peer->static_node->custom = uwsgi_now(); uwsgi_log("[uwsgi-%s] %.*s => marking %.*s as failed\n", ucr->short_name, (int) peer->key_len, peer->key, (int) peer->instance_address_len, peer->instance_address); } // check if the router supports the retry hook if (!peer->can_retry) goto end; if (peer->retries >= (size_t) ucr->max_retries) goto end; peer->retries++; // reset the peer uwsgi_cr_peer_reset(peer); // set new timeout peer->timeout = cr_add_timeout(ucr, peer); if (ucr->fallback) { // ok let's try with the fallback nodes if (!cs->fallback) { cs->fallback = ucr->fallback; } else { cs->fallback = cs->fallback->next; if (!cs->fallback) goto end; } peer->instance_address = cs->fallback->value; peer->instance_address_len = cs->fallback->len; if (cs->retry(peer)) { if (!peer->failed) goto end; } return; } peer->instance_address = NULL; peer->instance_address_len = 0; if (cs->retry(peer)) { if (!peer->failed) goto end; } return; } end: uwsgi_cr_peer_del(peer); if (peer == cs->main_peer) { cs->main_peer = NULL; corerouter_close_session(ucr, cs); } else { if (cs->can_keepalive == 0 && cs->wait_full_write == 0) { corerouter_close_session(ucr, cs); } } }