static void close_session(struct fastrouter_session **fr_table, struct fastrouter_session *fr_session) { // check timeout expired if (fr_session == NULL) { if (ufr.subscription_server) { //time_t current_time = time(NULL); uwsgi_log("checking for node health\n"); struct uwsgi_subscribe_slot *slot = ufr.subscriptions; while(slot) { struct uwsgi_subscribe_node *node = slot->nodes; while(node) { uwsgi_log("%.*s (hits: %llu) %.*s\n", slot->keylen, slot->key, slot->hits, node->len, node->name); node = node->next; } slot = slot->next; } del_check_timeout(ufr.subscriptions_check); ufr.subscriptions_check = add_check_timeout(10); } return; } close(fr_session->fd); fr_table[fr_session->fd] = NULL; if (fr_session->instance_fd != -1) { if (ufr.subscriptions && (fr_session->instance_failed || fr_session->status == FASTROUTER_STATUS_CONNECTING)) { if (fr_session->un && fr_session->un->len > 0) { uwsgi_log("[uwsgi-fastrouter] %.*s => marking %.*s as failed\n", (int) fr_session->hostname_len, fr_session->hostname, (int) fr_session->instance_address_len,fr_session->instance_address); uwsgi_remove_subscribe_node(&ufr.subscriptions, fr_session->un); if (ufr.subscriptions == NULL && ufr.cheap && !ufr.i_am_cheap) { uwsgi_log("[uwsgi-fastrouter] no more nodes available. Going cheap...\n"); struct uwsgi_fastrouter_socket *ufr_sock = ufr.sockets; while(ufr_sock) { event_queue_del_fd(ufr.queue, ufr_sock->fd, event_queue_read()); ufr_sock = ufr_sock->next; } ufr.i_am_cheap = 1; } } } close(fr_session->instance_fd); fr_table[fr_session->instance_fd] = NULL; } del_timeout(fr_session); free(fr_session); }
int uwsgi_fr_map_use_sctp(struct fastrouter_session *fr_session, char **magic_table) { if (!*uwsgi_fastrouter_sctp_nodes_current) *uwsgi_fastrouter_sctp_nodes_current = *uwsgi_fastrouter_sctp_nodes; struct uwsgi_fr_sctp_node *ufsn = *uwsgi_fastrouter_sctp_nodes_current; int choosen_fd = -1; // find the first available server while (ufsn) { if (ufr.fr_table[ufsn->fd]->status == FASTROUTER_STATUS_SCTP_NODE_FREE) { ufsn->requests++; choosen_fd = ufsn->fd; break; } if (ufsn->next == *uwsgi_fastrouter_sctp_nodes_current) { break; } ufsn = ufsn->next; } // no nodes available if (choosen_fd == -1) { fr_session->retry = 1; del_timeout(fr_session); fr_session->timeout = add_fake_timeout(fr_session); return -1; } struct sctp_sndrcvinfo sinfo; memset(&sinfo, 0, sizeof(struct sctp_sndrcvinfo)); memcpy(&sinfo.sinfo_ppid, &fr_session->uh, sizeof(uint32_t)); sinfo.sinfo_stream = fr_session->fd; ssize_t len = sctp_send(choosen_fd, fr_session->buffer, fr_session->uh.pktsize, &sinfo, 0); if (len < 0) uwsgi_error("sctp_send()"); fr_session->instance_fd = choosen_fd; fr_session->status = FASTROUTER_STATUS_SCTP_RESPONSE; ufr.fr_table[fr_session->instance_fd]->status = FASTROUTER_STATUS_SCTP_RESPONSE; ufr.fr_table[fr_session->instance_fd]->fd = fr_session->fd; // round robin *uwsgi_fastrouter_sctp_nodes_current = (*uwsgi_fastrouter_sctp_nodes_current)->next; return -1; }
static struct uwsgi_rb_timer *reset_timeout(struct fastrouter_session *fr_session) { del_timeout(fr_session); return add_timeout(fr_session); }