static void ngx_nats_process_reconnect(ngx_nats_data_t *nd) { if (nd->reconnect_timer.timer_set) { ngx_event_del_timer(&nd->reconnect_timer); } ngx_nats_connect(nd); }
ngx_int_t stop_spooler(channel_spooler_t *spl, uint8_t dequeue_subscribers) { ngx_rbtree_node_t *cur, *sentinel; spooler_event_ll_t *ecur, *ecur_next; subscriber_pool_t *spool; rbtree_seed_t *seed = &spl->spoolseed; ngx_rbtree_t *tree = &seed->tree; ngx_int_t n=0; sentinel = tree->sentinel; fetchmsg_data_t *dcur; #if NCHAN_RBTREE_DBG ngx_int_t active_before = seed->active_nodes, allocd_before = seed->active_nodes; #endif if(spl->running) { for(ecur = spl->spooler_dependent_events; ecur != NULL; ecur = ecur_next) { ecur_next = ecur->next; if(ecur->cancel) { ecur->cancel(ecur->ev.data); } ngx_event_del_timer(&ecur->ev); ngx_free(ecur); } for(cur = tree->root; cur != NULL && cur != sentinel; cur = tree->root) { spool = (subscriber_pool_t *)rbtree_data_from_node(cur); if(dequeue_subscribers) { destroy_spool(spool); } else { remove_spool(spool); rbtree_destroy_node(seed, cur); } n++; } for(dcur = spl->fetchmsg_cb_data_list; dcur != NULL; dcur = dcur->next) { dcur->spooler = NULL; } DBG("stopped %i spools in SPOOLER %p", n, *spl); } else { DBG("SPOOLER %p not running", *spl); } #if NCHAN_RBTREE_DBG assert(active_before - n == 0); assert(allocd_before - n == 0); assert(seed->active_nodes == 0); assert(seed->allocd_nodes == 0); #endif nchan_free_msg_id(&spl->prev_msg_id); spl->running = 0; return NGX_OK; }
static void ngx_nats_close_connection(ngx_nats_connection_t *nc, ngx_int_t reason, ngx_int_t reconnect) { ngx_connection_t *c = nc->pc.connection; ngx_nats_data_t *nd = nc->nd; ngx_nats_client_t **pclient; ngx_int_t i, n, immediate; if (nc->ping_timer.timer_set) { ngx_del_timer(&nc->ping_timer); } if (c->fd != -1) { ngx_close_connection(c); } if (c->read->timer_set) { ngx_event_del_timer(c->read); } if (c->write->timer_set) { ngx_event_del_timer(c->write); } immediate = 0; if (!(nc->state & NGX_NATS_STATE_BYTES_EXCHANGED)) { /* reconnect immediately because we simply could not connect */ immediate = 1; ngx_log_error(NGX_LOG_DEBUG, nc->nd->log, 0, "cannot connect to NATS at '%V'", &nc->server->url); } else if (nc->state == NGX_NATS_STATE_READY) { ngx_log_error(NGX_LOG_WARN, nc->nd->log, 0, "disconnected from NATS at '%V'", &nc->server->url); /* Call disconnected in clients */ n = nd->cd.clients.nelts; pclient = nd->cd.clients.elts; for (i = 0; i < n; i++, pclient++) { if ((*pclient)->disconnected) { (*pclient)->disconnected(*pclient); } } } else { /* TODO: handle partial connect */ } nd->cd.subs.nelts = 0; /* remove all subscriptions */ nd->cd.next_id = 0; nd->nc = NULL; /* clear buffers */ ngx_nats_buf_reset(nd->nc_read_buf); ngx_nats_buf_reset(nd->nc_write_buf); if (reconnect != 0) { /* * if we could not connect at all or simply disconnected * then try to reconnect immediately. * If we did connect and connection broke because of the internal * error or bad message from NATS then wait before reconnecting * so a poison pill message, or we're out of memory, do not put * us into a tight connection loop. */ if (reason == NGX_NATS_REASON_DISCONNECTED || immediate) { /* this reconnects immediately */ ngx_nats_process_reconnect(nd); } else { /* this runs timer, then reconnects */ ngx_nats_add_reconnect_timer(nd); } } }