static ngx_int_t spooler_add_subscriber(channel_spooler_t *self, subscriber_t *sub) { nchan_msg_id_t *msgid = &sub->last_msg_id; subscriber_pool_t *spool; if(self->want_to_stop) { ERR("Not accepting new subscribers right now. want to stop."); return NGX_ERROR; } spool = get_spool(self, msgid); assert(spool->id.time == msgid->time); if(spool == NULL) { return NGX_ERROR; } if(spool_add_subscriber(spool, sub, 1) != NGX_OK) { ERR("couldn't add subscriber to spool %p", spool); return NGX_ERROR; } if(self->add_handler != NULL) { self->add_handler(self, sub, self->add_handler_privdata); } else { ERR("SPOOLER %p has no add_handler, couldn't add subscriber %p", self, sub); } switch(spool->msg_status) { case MSG_FOUND: assert(spool->msg); spool_respond_general(spool, spool->msg, 0, NULL); break; case MSG_INVALID: assert(spool->msg == NULL); spool_fetch_msg(spool); break; case MSG_CHANNEL_NOTREADY: case MSG_PENDING: case MSG_EXPECTED: //nothing to do but wait break; case MSG_EXPIRED: case MSG_NOTFOUND: //shouldn't happen assert(0); } return NGX_OK; }
static ngx_int_t spool_transfer_subscribers(subscriber_pool_t *spool, subscriber_pool_t *newspool, uint8_t update_subscriber_last_msgid) { ngx_int_t count = 0; subscriber_t *sub; spooled_subscriber_t *cur; assert(spool->spooler == newspool->spooler); if(spool == NULL || newspool == NULL) { ERR("failed to transfer spool subscribers"); return 0; } for(cur = spool->first; cur != NULL; cur = spool->first) { sub = cur->sub; spool_remove_subscriber(spool, cur); if(update_subscriber_last_msgid) { sub->last_msg_id=newspool->id; } spool_add_subscriber(newspool, sub, 0); count++; } return count; }
static ngx_int_t spooler_add_subscriber(channel_spooler_t *self, subscriber_t *sub) { nchan_msg_id_t *msgid = &sub->last_msgid; subscriber_pool_t *spool; subscriber_type_t subtype; if(self->want_to_stop) { ERR("Not accepting new subscribers right now. want to stop."); return NGX_ERROR; } //validate_spooler(self, "before add_subscriber"); spool = get_spool(self, msgid); assert(spool->id.time == msgid->time); if(spool == NULL) { return NGX_ERROR; } subtype = sub->type; if(spool_add_subscriber(spool, sub, 1) != NGX_OK) { ERR("couldn't add subscriber to spool %p", spool); return NGX_ERROR; } self->handlers->add(self, sub, self->handlers_privdata); switch(spool->msg_status) { case MSG_FOUND: assert(spool->msg); spool_respond_general(spool, spool->msg, 0, NULL, 0); break; case MSG_INVALID: assert(spool->msg == NULL); spool_fetch_msg(spool); break; case MSG_CHANNEL_NOTREADY: case MSG_PENDING: //nothing to do break; case MSG_EXPECTED: //notify subscriber sub->fn->respond_status(sub, NGX_HTTP_NO_CONTENT, NULL); break; case MSG_EXPIRED: case MSG_NOTFOUND: case MSG_NORESPONSE: //shouldn't happen assert(0); } if(self->handlers->bulk_post_subscribe != NULL && subtype != INTERNAL) { self->handlers->bulk_post_subscribe(self, 1, self->handlers_privdata); } //validate_spooler(self, "after add_subscriber"); return NGX_OK; }