static rstatus_t stats_pool_init(struct stats_pool *stp, struct server_pool *sp) { rstatus_t status; stp->name = sp->name; array_null(&stp->metric); array_null(&stp->server); status = stats_pool_metric_init(&stp->metric); if (status != NC_OK) { return status; } status = stats_server_map(&stp->server, &sp->server); if (status != NC_OK) { stats_metric_deinit(&stp->metric); return status; } log_debug(LOG_VVVERB, "init stats pool '%.*s' with %"PRIu32" metric and " "%"PRIu32" server", stp->name.len, stp->name.data, array_n(&stp->metric), array_n(&stp->metric)); return NC_OK; }
//把stats_pool_codec数组成员赋值给stats_pool->metric数组 //把stats_server_codec数组成员赋值给stats_pool->server数组中的相关成员 static rstatus_t stats_pool_init(struct stats_pool *stp, struct server_pool *sp) { rstatus_t status; stp->name = sp->name; array_null(&stp->metric); array_null(&stp->server); //把stats_pool_codec中的成员拷贝到stats_pool->metric status = stats_pool_metric_init(&stp->metric);//把stats_pool_codec数组成员赋值给stats_pool->metric数组 if (status != NC_OK) { return status; } //把stats_server_codec数组成员赋值给stats_pool->server数组中的相关成员 //大server中的server:配置列表有多少个,这里的stats_pool->server数组就有多少个成员 status = stats_server_map(&stp->server, &sp->server); //sp->server这个是配置文件中每个大server中对应的servers: if (status != NC_OK) { stats_metric_deinit(&stp->metric); return status; } log_debug(LOG_VVVERB, "init stats pool '%.*s' with %"PRIu32" metric and " "%"PRIu32" server", stp->name.len, stp->name.data, array_n(&stp->metric), array_n(&stp->metric)); return NC_OK; }
rstatus_t stats_pool_copy_init(struct stats_pool *stp, struct server_pool *sp, struct hash_table **sit) { rstatus_t status; uint32_t nserver; string_init(&stp->name); string_duplicate(&stp->name, &sp->name); array_null(&stp->metric); array_null(&stp->server); status = array_init(&stp->metric, STATS_POOL_NFIELD, sizeof(struct stats_metric)); if (status != NC_OK) { return status; } nserver = array_n(&sp->server) == 0 ? array_n(&stp->server):array_n(&sp->server); status = array_init(&stp->server, nserver, sizeof(struct stats_server)); if (status != NC_OK) { return status; } (*sit) = assoc_create_table(sp->key_hash, array_n(&sp->server)); if ((*sit) == NULL) { return NC_ERROR; } return NC_OK; }
static rstatus_t conf_pool_init(struct conf_pool *cp, struct string *name) { rstatus_t status; string_init(&cp->name); string_init(&cp->listen.pname); string_init(&cp->listen.name); cp->listen.port = 0; memset(&cp->listen.info, 0, sizeof(cp->listen.info)); cp->listen.valid = 0; cp->hash = CONF_UNSET_HASH; string_init(&cp->hash_tag); cp->distribution = CONF_UNSET_DIST; cp->timeout = CONF_UNSET_NUM; cp->backlog = CONF_UNSET_NUM; cp->client_connections = CONF_UNSET_NUM; cp->tcpkeepalive = CONF_UNSET_NUM; string_init(&cp->redis_auth); cp->redis_db = CONF_UNSET_NUM; cp->server_connections = CONF_UNSET_NUM; array_null(&cp->groups); cp->sentinel_heartbeat = CONF_UNSET_NUM; array_null(&cp->sentinels); cp->valid = 0; status = string_duplicate(&cp->name, name); if (status != NC_OK) { return status; } status = array_init(&cp->groups, CONF_DEFAULT_GROUPS, sizeof(struct string)); if (status != NC_OK) { string_deinit(&cp->name); return status; } status = array_init(&cp->sentinels, CONF_DEFAULT_SENTINELS, sizeof(struct conf_server)); if (status != NC_OK) { array_deinit(&cp->groups); string_deinit(&cp->name); return status; } log_debug(LOG_VVERB, "init conf pool %p, '%.*s'", cp, name->len, name->data); return NC_OK; }
static rstatus_t conf_pool_init(struct conf_pool *cp, struct string *name) { rstatus_t status; string_init(&cp->name); string_init(&cp->listen.pname); string_init(&cp->listen.name); string_init(&cp->redis_auth); cp->listen.port = 0; memset(&cp->listen.info, 0, sizeof(cp->listen.info)); cp->listen.valid = 0; cp->hash = CONF_UNSET_HASH; string_init(&cp->hash_tag); cp->distribution = CONF_UNSET_DIST; cp->timeout = CONF_UNSET_NUM; cp->backlog = CONF_UNSET_NUM; cp->client_connections = CONF_UNSET_NUM; cp->redis = CONF_UNSET_NUM; cp->tcpkeepalive = CONF_UNSET_NUM; cp->redis_db = CONF_UNSET_NUM; cp->proto = CONF_UNSET_PROTO; cp->preconnect = CONF_UNSET_NUM; cp->auto_eject_hosts = CONF_UNSET_NUM; cp->server_connections = CONF_UNSET_NUM; cp->server_retry_timeout = CONF_UNSET_NUM; cp->server_failure_limit = CONF_UNSET_NUM; array_null(&cp->server); cp->valid = 0; status = string_duplicate(&cp->name, name); if (status != NC_OK) { return status; } status = array_init(&cp->server, CONF_DEFAULT_SERVERS, sizeof(struct conf_server)); if (status != NC_OK) { string_deinit(&cp->name); return status; } log_debug(LOG_VVERB, "init conf pool %p, '%.*s'", cp, name->len, name->data); return NC_OK; }
static rstatus_t stats_server_init(struct stats_server *sts, struct server *s) { rstatus_t status; sts->name = s->name; array_null(&sts->metric); status = stats_server_metric_init(sts); if (status != NC_OK) { return status; } log_debug(LOG_VVVERB, "init stats server '%.*s' with %"PRIu32" metric", sts->name.len, sts->name.data, array_n(&sts->metric)); return NC_OK; }
rstatus_t conf_pool_each_transform(void *elem, void *data) { rstatus_t status; struct conf_pool *cp = elem; struct array *server_pool = data; struct server_pool *sp; ASSERT(cp->valid); sp = array_push(server_pool); ASSERT(sp != NULL); sp->idx = array_idx(server_pool, sp); sp->ctx = NULL; sp->p_conn = NULL; sp->nc_conn_q = 0; TAILQ_INIT(&sp->c_conn_q); array_null(&sp->server); sp->ncontinuum = 0; sp->nserver_continuum = 0; sp->continuum = NULL; sp->nlive_server = 0; sp->next_rebuild = 0LL; sp->name = cp->name; sp->addrstr = cp->listen.pname; sp->port = (uint16_t)cp->listen.port; sp->family = cp->listen.info.family; sp->addrlen = cp->listen.info.addrlen; sp->addr = (struct sockaddr *)&cp->listen.info.addr; sp->dist_type = cp->distribution; sp->key_hash_type = cp->hash; sp->key_hash = hash_algos[cp->hash]; sp->timeout = cp->timeout; sp->backlog = cp->backlog; sp->item_size_max = (uint32_t)cp->item_size_max; sp->client_connections = (uint32_t)cp->client_connections; sp->server_connections = (uint32_t)cp->server_connections; sp->server_retry_timeout = (int64_t)cp->server_retry_timeout * 1000LL; sp->server_failure_limit = (uint32_t)cp->server_failure_limit; sp->auto_eject_hosts = cp->auto_eject_hosts ? 1 : 0; sp->preconnect = cp->preconnect ? 1 : 0; status = server_init(&sp->server, &cp->server, sp); if (status != NC_OK) { return status; } log_debug(LOG_VERB, "transform to pool %"PRIu32" '%.*s'", sp->idx, sp->name.len, sp->name.data); return NC_OK; }
struct stats * stats_create(uint16_t stats_port, char *stats_ip, int stats_interval, char *source, struct array *server_pool) { rstatus_t status; struct stats *st; char *server_name; st = nc_alloc(sizeof(*st)); if (st == NULL) { return NULL; } st->port = stats_port; st->interval = stats_interval; string_set_raw(&st->addr, stats_ip); st->start_ts = (int64_t)time(NULL); st->buf.len = 0; st->buf.data = NULL; st->buf.size = 0; array_null(&st->current); array_null(&st->shadow); array_null(&st->sum); st->tid = (pthread_t) -1; st->sd = -1; string_set_text(&st->service_str, "service"); //string_set_text(&st->service, "bilitw"); server_name = nc_alloc(100); memset(server_name, 0, 100); sprintf(server_name, "bilitw worker %d", nc_worker_index); string_set_raw(&st->service, server_name); //&st->service->len = strlen(server_name) + 1; //&st->service->data = (uint8_t *)server_name; string_set_text(&st->source_str, "source"); string_set_raw(&st->source, source); string_set_text(&st->version_str, "version"); string_set_text(&st->version, NC_VERSION_STRING); string_set_text(&st->uptime_str, "uptime"); string_set_text(&st->timestamp_str, "timestamp"); string_set_text(&st->ntotal_conn_str, "total_connections"); string_set_text(&st->ncurr_conn_str, "curr_connections"); st->updated = 0; st->aggregate = 0; /* map server pool to current (a), shadow (b) and sum (c) */ status = stats_pool_map(&st->current, server_pool); if (status != NC_OK) { goto error; } status = stats_pool_map(&st->shadow, server_pool); if (status != NC_OK) { goto error; } status = stats_pool_map(&st->sum, server_pool); if (status != NC_OK) { goto error; } status = stats_create_buf(st); if (status != NC_OK) { goto error; } status = stats_start_aggregator(st); if (status != NC_OK) { goto error; } return st; error: stats_destroy(st); return NULL; }
static struct context * core_ctx_create(struct instance *nci) { rstatus_t status; struct context *ctx; struct conn *sentinel_conn; ctx = nc_alloc(sizeof(*ctx)); if (ctx == NULL) { return NULL; } ctx->id = ++ctx_id; ctx->cf = NULL; ctx->stats = NULL; array_null(&ctx->pool); ctx->ep = -1; ctx->nevent = EVENT_SIZE_HINT; ctx->max_timeout = nci->stats_interval; ctx->timeout = ctx->max_timeout; ctx->event = NULL; ctx->server_reconnect_interval = nci->server_reconnect_interval; ctx->whitelist = nci->whitelist; /* parse and create configuration */ ctx->cf = conf_create(nci->conf_filename); if (ctx->cf == NULL) { nc_free(ctx); return NULL; } /* initialize server pool from configuration */ status = server_pool_init(&ctx->pool, &ctx->cf->pool, ctx); if (status != NC_OK) { conf_destroy(ctx->cf); nc_free(ctx); return NULL; } /* initialize sentinel server */ ctx->sentinel = sentinel_init(nci->sentinel_port, nci->sentinel_addr); if (ctx->sentinel == NULL) { server_pool_deinit(&ctx->pool); conf_destroy(ctx->cf); nc_free(ctx); return NULL; } /* create stats per server pool */ ctx->stats = stats_create(nci->stats_port, nci->stats_addr, nci->stats_interval, nci->hostname, &ctx->pool); if (ctx->stats == NULL) { sentinel_deinit(ctx->sentinel); server_pool_deinit(&ctx->pool); conf_destroy(ctx->cf); nc_free(ctx); return NULL; } /* initialize event handling for client, proxy and server */ status = event_init(ctx, EVENT_SIZE_HINT); if (status != NC_OK) { stats_destroy(ctx->stats); sentinel_deinit(ctx->sentinel); server_pool_deinit(&ctx->pool); conf_destroy(ctx->cf); nc_free(ctx); return NULL; } /* preconnect? servers in server pool */ status = server_pool_preconnect(ctx); if (status != NC_OK) { server_pool_disconnect(ctx); event_deinit(ctx); stats_destroy(ctx->stats); sentinel_deinit(ctx->sentinel); server_pool_deinit(&ctx->pool); conf_destroy(ctx->cf); nc_free(ctx); return NULL; } /* initialize sentinel server conn */ sentinel_conn = sentinel_connect(ctx); if (sentinel_conn == NULL) { server_pool_disconnect(ctx); event_deinit(ctx); stats_destroy(ctx->stats); sentinel_deinit(ctx->sentinel); server_pool_deinit(&ctx->pool); conf_destroy(ctx->cf); nc_free(ctx); } /* initialize proxy per server pool */ status = proxy_init(ctx); if (status != NC_OK) { sentinel_conn->close(ctx, sentinel_conn); server_pool_disconnect(ctx); event_deinit(ctx); stats_destroy(ctx->stats); sentinel_deinit(ctx->sentinel); server_pool_deinit(&ctx->pool); conf_destroy(ctx->cf); nc_free(ctx); return NULL; } log_debug(LOG_VVERB, "created ctx %p id %"PRIu32"", ctx, ctx->id); return ctx; }
struct stats * stats_create(uint16_t stats_port, char *stats_ip, int stats_interval, char *source, struct array *server_pool) { rstatus_t status; struct stats *st; st = nc_alloc(sizeof(*st)); if (st == NULL) { return NULL; } st->port = stats_port; st->interval = stats_interval; string_set_raw(&st->addr, stats_ip); st->start_ts = (int64_t)time(NULL); st->buf.len = 0; st->buf.data = NULL; st->buf.size = 0; array_null(&st->current); array_null(&st->shadow); array_null(&st->sum); st->tid = (pthread_t) -1; st->sd = -1; string_set_text(&st->service_str, "service"); string_set_text(&st->service, "nutcracker"); string_set_text(&st->source_str, "source"); string_set_raw(&st->source, source); string_set_text(&st->version_str, "version"); string_set_text(&st->version, NC_VERSION_STRING); string_set_text(&st->uptime_str, "uptime"); string_set_text(&st->timestamp_str, "timestamp"); string_set_text(&st->ntotal_conn_str, "total_connections"); string_set_text(&st->ncurr_conn_str, "curr_connections"); st->updated = 0; st->aggregate = 0; /* map server pool to current (a), shadow (b) and sum (c) */ status = stats_pool_map(&st->current, server_pool); if (status != NC_OK) { goto error; } status = stats_pool_map(&st->shadow, server_pool); if (status != NC_OK) { goto error; } status = stats_pool_map(&st->sum, server_pool); if (status != NC_OK) { goto error; } status = stats_create_buf(st); //为stats格式信息分配buf空间 if (status != NC_OK) { goto error; } //stats状态信息专门起一个线程来处理 status = stats_start_aggregator(st); if (status != NC_OK) { goto error; } return st; error: stats_destroy(st); return NULL; }
static struct context * core_ctx_create(struct instance *nci) { rstatus_t status; struct context *ctx; srand((unsigned) time(NULL)); ctx = dn_alloc(sizeof(*ctx)); if (ctx == NULL) { return NULL; } ctx->id = ++ctx_id; ctx->cf = NULL; ctx->stats = NULL; ctx->evb = NULL; array_null(&ctx->pool); ctx->max_timeout = nci->stats_interval; ctx->timeout = ctx->max_timeout; ctx->dyn_state = INIT; /* parse and create configuration */ ctx->cf = conf_create(nci->conf_filename); if (ctx->cf == NULL) { loga("Failed to create context!!!"); dn_free(ctx); return NULL; } /* initialize server pool from configuration */ status = server_pool_init(&ctx->pool, &ctx->cf->pool, ctx); if (status != DN_OK) { loga("Failed to initialize server pool!!!"); conf_destroy(ctx->cf); dn_free(ctx); return NULL; } /* crypto init */ status = crypto_init(ctx); if (status != DN_OK) { loga("Failed to initialize crypto!!!"); dn_free(ctx); return NULL; } /* create stats per server pool */ ctx->stats = stats_create(nci->stats_port, nci->stats_addr, nci->stats_interval, nci->hostname, &ctx->pool, ctx); if (ctx->stats == NULL) { loga("Failed to create stats!!!"); crypto_deinit(); server_pool_deinit(&ctx->pool); conf_destroy(ctx->cf); dn_free(ctx); return NULL; } /* initialize event handling for client, proxy and server */ ctx->evb = event_base_create(EVENT_SIZE, &core_core); if (ctx->evb == NULL) { loga("Failed to create socket event handling!!!"); crypto_deinit(); stats_destroy(ctx->stats); server_pool_deinit(&ctx->pool); conf_destroy(ctx->cf); dn_free(ctx); return NULL; } /* preconnect? servers in server pool */ status = server_pool_preconnect(ctx); if (status != DN_OK) { loga("Failed to preconnect for server pool!!!"); crypto_deinit(); server_pool_disconnect(ctx); event_base_destroy(ctx->evb); stats_destroy(ctx->stats); server_pool_deinit(&ctx->pool); conf_destroy(ctx->cf); dn_free(ctx); return NULL; } /* initialize proxy per server pool */ status = proxy_init(ctx); if (status != DN_OK) { loga("Failed to initialize proxy!!!"); crypto_deinit(); server_pool_disconnect(ctx); event_base_destroy(ctx->evb); stats_destroy(ctx->stats); server_pool_deinit(&ctx->pool); conf_destroy(ctx->cf); dn_free(ctx); return NULL; } /* initialize dnode listener per server pool */ status = dnode_init(ctx); if (status != DN_OK) { loga("Failed to initialize dnode!!!"); crypto_deinit(); server_pool_disconnect(ctx); event_base_destroy(ctx->evb); stats_destroy(ctx->stats); server_pool_deinit(&ctx->pool); conf_destroy(ctx->cf); dn_free(ctx); return NULL; } ctx->dyn_state = JOINING; //TODOS: change this to JOINING /* initialize peers */ status = dnode_peer_init(&ctx->pool, ctx); if (status != DN_OK) { loga("Failed to initialize dnode peers!!!"); crypto_deinit(); dnode_deinit(ctx); server_pool_disconnect(ctx); event_base_destroy(ctx->evb); stats_destroy(ctx->stats); server_pool_deinit(&ctx->pool); conf_destroy(ctx->cf); dn_free(ctx); return NULL; } core_debug(ctx); /* preconntect peers - probably start gossip here */ status = dnode_peer_pool_preconnect(ctx); if (status != DN_OK) { loga("Failed to preconnect dnode peers!!!"); crypto_deinit(); dnode_peer_deinit(&ctx->pool); dnode_deinit(ctx); server_pool_disconnect(ctx); event_base_destroy(ctx->evb); stats_destroy(ctx->stats); server_pool_deinit(&ctx->pool); conf_destroy(ctx->cf); dn_free(ctx); return NULL; } //init ring msg queue CBUF_Init(C2G_InQ); CBUF_Init(C2G_OutQ); //init stats msg queue CBUF_Init(C2S_InQ); CBUF_Init(C2S_OutQ); gossip_pool_init(ctx); log_debug(LOG_VVERB, "created ctx %p id %"PRIu32"", ctx, ctx->id); return ctx; }
void array_destroy( array_t *a ) { free( a->data ); *a = array_null(); }
static struct context * core_ctx_create(struct instance *nci) { rstatus_t status; struct context *ctx; ctx = nc_alloc(sizeof(*ctx)); if (ctx == NULL) { return NULL; } ctx->id = ++ctx_id; ctx->cf = NULL; ctx->stats = NULL; ctx->evb = NULL; array_null(&ctx->pool); ctx->max_timeout = nci->stats_interval; ctx->timeout = ctx->max_timeout; ctx->max_nfd = 0; ctx->max_ncconn = 0; ctx->max_nsconn = 0; /* parse and create configuration */ ctx->cf = conf_create(nci->conf_filename); if (ctx->cf == NULL) { nc_free(ctx); return NULL; } /* initialize server pool from configuration */ status = server_pool_init(&ctx->pool, &ctx->cf->pool, ctx); if (status != NC_OK) { conf_destroy(ctx->cf); nc_free(ctx); return NULL; } /* * Get rlimit and calculate max client connections after we have * calculated max server connections */ status = core_calc_connections(ctx); if (status != NC_OK) { server_pool_deinit(&ctx->pool); conf_destroy(ctx->cf); nc_free(ctx); return NULL; } /* create stats per server pool */ ctx->stats = stats_create(nci->stats_port, nci->stats_addr, nci->stats_interval, nci->hostname, &ctx->pool); if (ctx->stats == NULL) { server_pool_deinit(&ctx->pool); conf_destroy(ctx->cf); nc_free(ctx); return NULL; } /* initialize event handling for client, proxy and server */ ctx->evb = event_base_create(EVENT_SIZE, &core_core); if (ctx->evb == NULL) { stats_destroy(ctx->stats); server_pool_deinit(&ctx->pool); conf_destroy(ctx->cf); nc_free(ctx); return NULL; } /* preconnect? servers in server pool */ status = server_pool_preconnect(ctx); if (status != NC_OK) { server_pool_disconnect(ctx); event_base_destroy(ctx->evb); stats_destroy(ctx->stats); server_pool_deinit(&ctx->pool); conf_destroy(ctx->cf); nc_free(ctx); return NULL; } /* initialize proxy per server pool */ status = proxy_init(ctx); if (status != NC_OK) { server_pool_disconnect(ctx); event_base_destroy(ctx->evb); stats_destroy(ctx->stats); server_pool_deinit(&ctx->pool); conf_destroy(ctx->cf); nc_free(ctx); return NULL; } log_debug(LOG_VVERB, "created ctx %p id %"PRIu32"", ctx, ctx->id); return ctx; }
struct stats * stats_create(uint16_t stats_port, char *stats_ip, int stats_interval, char *source, struct array *server_pool, struct context *ctx) { rstatus_t status; struct stats *st; st = dn_alloc(sizeof(*st)); if (st == NULL) { return NULL; } st->port = stats_port; st->interval = stats_interval; string_set_raw(&st->addr, stats_ip); st->start_ts = (int64_t)time(NULL); st->buf.len = 0; st->buf.data = NULL; st->buf.size = 0; array_null(&st->current); array_null(&st->shadow); array_null(&st->sum); st->tid = (pthread_t) -1; st->sd = -1; string_set_text(&st->service_str, "service"); string_set_text(&st->service, "dynomite"); string_set_text(&st->source_str, "source"); string_set_raw(&st->source, source); string_set_text(&st->version_str, "version"); string_set_text(&st->version, DN_VERSION_STRING); string_set_text(&st->uptime_str, "uptime"); string_set_text(&st->timestamp_str, "timestamp"); //for latency histo string_set_text(&st->latency_999th_str, "latency_999th"); string_set_text(&st->latency_99th_str, "latency_99th"); string_set_text(&st->latency_95th_str, "latency_95th"); string_set_text(&st->latency_mean_str, "latency_mean"); string_set_text(&st->latency_max_str, "latency_max"); //for payload size histo string_set_text(&st->payload_size_999th_str, "payload_size_999th"); string_set_text(&st->payload_size_99th_str, "payload_size_99th"); string_set_text(&st->payload_size_95th_str, "payload_size_95th"); string_set_text(&st->payload_size_mean_str, "payload_size_mean"); string_set_text(&st->payload_size_max_str, "payload_size_max"); string_set_text(&st->alloc_msgs_str, "alloc_msgs"); //only display the first pool struct server_pool *sp = (struct server_pool*) array_get(server_pool, 0); string_set_text(&st->rack_str, "rack"); string_copy(&st->rack, sp->rack.data, sp->rack.len); string_set_text(&st->dc_str, "dc"); string_copy(&st->dc, sp->dc.data, sp->dc.len); st->updated = 0; st->aggregate = 0; histo_init(&st->latency_histo); histo_init(&st->payload_size_histo); st->alloc_msgs = 0; /* map server pool to current (a), shadow (b) and sum (c) */ status = stats_pool_map(&st->current, server_pool); if (status != DN_OK) { goto error; } status = stats_pool_map(&st->shadow, server_pool); if (status != DN_OK) { goto error; } status = stats_pool_map(&st->sum, server_pool); if (status != DN_OK) { goto error; } status = stats_create_buf(st); if (status != DN_OK) { goto error; } status = stats_start_aggregator(st); if (status != DN_OK) { goto error; } st->ctx = ctx; return st; error: stats_destroy(st); return NULL; }
static struct context * core_ctx_create(struct instance *nci) { rstatus_t status; struct context *ctx; int64_t now; uint32_t npool; ctx = nc_alloc(sizeof(*ctx)); if (ctx == NULL) { return NULL; } now = nc_msec_now(); if (now < 0) { nc_free(ctx); return NULL; } ctx->id = ++ctx_id; ctx->cf = NULL; ctx->stats = NULL; ctx->evb = NULL; array_null(&ctx->pool); ctx->max_timeout = nci->stats_interval; ctx->timeout = ctx->max_timeout; ctx->next_tick = now + NC_TICK_INTERVAL; /* parse and create configuration */ ctx->cf = conf_create(nci->conf_filename); if (ctx->cf == NULL) { nc_free(ctx); return NULL; } npool = array_n(&ctx->cf->pool); /* initialize server pool from configuration */ if (npool != 0) { status = server_pool_init(&ctx->pool, &ctx->cf->pool, ctx); if (status != NC_OK) { conf_destroy(ctx->cf); nc_free(ctx); return NULL; } } /* create stats per server pool */ if (npool != 0) { ctx->stats = stats_create(nci->stats_port, nci->stats_addr, nci->stats_interval, nci->hostname, &ctx->pool); if (ctx->stats == NULL) { server_pool_deinit(&ctx->pool); conf_destroy(ctx->cf); nc_free(ctx); return NULL; } } /* initialize event handling for client, proxy and server */ ctx->evb = evbase_create(NC_EVENT_SIZE, &core_core); if (ctx->evb == NULL) { stats_destroy(ctx->stats); server_pool_deinit(&ctx->pool); conf_destroy(ctx->cf); nc_free(ctx); return NULL; } /* preconnect? servers in server pool */ if (npool != 0) { status = server_pool_preconnect(ctx); if (status != NC_OK) { server_pool_disconnect(ctx); evbase_destroy(ctx->evb); stats_destroy(ctx->stats); server_pool_deinit(&ctx->pool); conf_destroy(ctx->cf); nc_free(ctx); return NULL; } } /* initialize proxy per server pool */ if (npool != 0) { status = proxy_init(ctx); if (status != NC_OK) { server_pool_disconnect(ctx); evbase_destroy(ctx->evb); stats_destroy(ctx->stats); server_pool_deinit(&ctx->pool); conf_destroy(ctx->cf); nc_free(ctx); return NULL; } } log_debug(LOG_VVERB, "created ctx %p id %"PRIu32"", ctx, ctx->id); return ctx; }
rstatus_t conf_pool_each_transform(void *elem, void *data) { rstatus_t status; struct conf_pool *cp = elem; struct array *server_pool = data; struct server_pool *sp; ASSERT(cp->valid); sp = array_push(server_pool); ASSERT(sp != NULL); sp->idx = array_idx(server_pool, sp); sp->ctx = NULL; sp->p_conn = NULL; sp->nc_conn_q = 0; TAILQ_INIT(&sp->c_conn_q); sp->state = STATE_UNINITLIAZED; array_null(&sp->groups); array_null(&sp->sentinels); sp->sentinel = NULL; sp->sentinel_heartbeat = (uint32_t)cp->sentinel_heartbeat; array_null(&sp->server); sp->ncontinuum = 0; sp->nserver_continuum = 0; sp->continuum = NULL; sp->nlive_server = 0; sp->name = cp->name; sp->addrstr = cp->listen.pname; sp->port = (uint16_t)cp->listen.port; nc_memcpy(&sp->info, &cp->listen.info, sizeof(cp->listen.info)); sp->perm = cp->listen.perm; sp->dist_type = cp->distribution; sp->key_hash_type = cp->hash; sp->key_hash = hash_algos[cp->hash]; sp->hash_tag = cp->hash_tag; sp->timeout = cp->timeout; sp->backlog = cp->backlog; sp->redis_db = cp->redis_db; sp->client_connections = (uint32_t)cp->client_connections; sp->server_connections = (uint32_t)cp->server_connections; sp->redis_auth = cp->redis_auth; sp->require_auth = cp->redis_auth.len > 0 ? 1 : 0; sp->tcpkeepalive = cp->tcpkeepalive ? 1 : 0; sp->groups = cp->groups; status = server_init(&sp->server, &sp->groups, sp); if (status != NC_OK) { return status; } status = sentinel_init(&sp->sentinels, &cp->sentinels, sp); if (status != NC_OK) { return status; } log_debug(LOG_VERB, "transform to pool %"PRIu32" '%.*s'", sp->idx, sp->name.len, sp->name.data); return NC_OK; }