diff --git a/src/stratifier.c b/src/stratifier.c index da9b545b..57a9ef08 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -41,6 +41,8 @@ struct pool_stats { int workers; int users; + int disconnected; + int dead; /* Absolute shares stats */ int64_t unaccounted_shares; @@ -856,6 +858,12 @@ static void update_base(ckpool_t *ckp, int prio) create_pthread(pth, do_update, ur); } +static void __del_disconnected(sdata_t *sdata, stratum_instance_t *client) +{ + HASH_DEL(sdata->disconnected_instances, client); + sdata->stats.disconnected--; +} + static void drop_allclients(ckpool_t *ckp) { stratum_instance_t *client, *tmp; @@ -868,8 +876,9 @@ static void drop_allclients(ckpool_t *ckp) sprintf(buf, "dropclient=%ld", client->id); send_proc(ckp->connector, buf); } - HASH_ITER(hh, sdata->disconnected_instances, client, tmp) - HASH_DEL(sdata->disconnected_instances, client); + HASH_ITER(hh, sdata->disconnected_instances, client, tmp) { + __del_disconnected(sdata, client); + } sdata->stats.users = sdata->stats.workers = 0; ck_wunlock(&sdata->instance_lock); } @@ -1213,6 +1222,18 @@ static void dec_worker(ckpool_t *ckp, user_instance_t *instance) mutex_unlock(&sdata->stats_lock); } +static void __add_dead(sdata_t *sdata, stratum_instance_t *client) +{ + LL_PREPEND(sdata->dead_instances, client); + sdata->stats.dead++; +} + +static void __del_dead(sdata_t *sdata, stratum_instance_t *client) +{ + LL_DELETE(sdata->dead_instances, client); + sdata->stats.dead--; +} + static void drop_client(sdata_t *sdata, int64_t id) { stratum_instance_t *client, *tmp; @@ -1237,12 +1258,13 @@ static void drop_client(sdata_t *sdata, int64_t id) HASH_DEL(sdata->stratum_instances, client); HASH_FIND(hh, sdata->disconnected_instances, &client->enonce1_64, sizeof(uint64_t), old_client); /* Only keep around one copy of the old client in server mode */ - if (!client->ckp->proxy && !old_client && client->enonce1_64 && dec) + if (!client->ckp->proxy && !old_client && client->enonce1_64 && dec) { HASH_ADD(hh, sdata->disconnected_instances, enonce1_64, sizeof(uint64_t), client); - else { + sdata->stats.disconnected++; + } else { if (client->user_instance) DL_DELETE(client->user_instance->instances, client); - LL_PREPEND(sdata->dead_instances, client); + __add_dead(sdata, client); } } /* Cull old unused clients lazily when there are no more reference @@ -1250,7 +1272,7 @@ static void drop_client(sdata_t *sdata, int64_t id) LL_FOREACH_SAFE(sdata->dead_instances, client, tmp) { if (!client->ref) { LOGINFO("Stratifier discarding instance %ld", client->id); - LL_DELETE(sdata->dead_instances, client); + __del_dead(sdata, client); free(client->workername); free(client->useragent); free(client); @@ -3484,6 +3506,7 @@ static void *statsupdate(void *arg) user_instance_t *instance, *tmpuser; stratum_instance_t *client, *tmp; double sps1, sps5, sps15, sps60; + int idle_workers = 0; char fname[512] = {}; tv_t now, diff; ts_t ts_now; @@ -3496,78 +3519,6 @@ static void *statsupdate(void *arg) timersub(&now, &stats->start_time, &diff); tdiff = diff.tv_sec + (double)diff.tv_usec / 1000000; - ghs1 = stats->dsps1 * nonces; - suffix_string(ghs1, suffix1, 16, 0); - sps1 = stats->sps1; - - bias = !CKP_STANDALONE(ckp) ? 1.0 : time_bias(tdiff, 300); - ghs5 = stats->dsps5 * nonces / bias; - sps5 = stats->sps5 / bias; - suffix_string(ghs5, suffix5, 16, 0); - - bias = !CKP_STANDALONE(ckp) ? 1.0 : time_bias(tdiff, 900); - ghs15 = stats->dsps15 * nonces / bias; - suffix_string(ghs15, suffix15, 16, 0); - sps15 = stats->sps15 / bias; - - bias = !CKP_STANDALONE(ckp) ? 1.0 : time_bias(tdiff, 3600); - ghs60 = stats->dsps60 * nonces / bias; - sps60 = stats->sps60 / bias; - suffix_string(ghs60, suffix60, 16, 0); - - bias = !CKP_STANDALONE(ckp) ? 1.0 : time_bias(tdiff, 21600); - ghs360 = stats->dsps360 * nonces / bias; - suffix_string(ghs360, suffix360, 16, 0); - - bias = !CKP_STANDALONE(ckp) ? 1.0 : time_bias(tdiff, 86400); - ghs1440 = stats->dsps1440 * nonces / bias; - suffix_string(ghs1440, suffix1440, 16, 0); - - bias = !CKP_STANDALONE(ckp) ? 1.0 : time_bias(tdiff, 604800); - ghs10080 = stats->dsps10080 * nonces / bias; - suffix_string(ghs10080, suffix10080, 16, 0); - - snprintf(fname, 511, "%s/pool/pool.status", ckp->logdir); - fp = fopen(fname, "we"); - if (unlikely(!fp)) - LOGERR("Failed to fopen %s", fname); - - JSON_CPACK(val, "{si,si,si}", - "runtime", diff.tv_sec, - "Users", stats->users, - "Workers", stats->workers); - s = json_dumps(val, JSON_NO_UTF8 | JSON_PRESERVE_ORDER); - json_decref(val); - LOGNOTICE("Pool:%s", s); - fprintf(fp, "%s\n", s); - dealloc(s); - - JSON_CPACK(val, "{ss,ss,ss,ss,ss,ss,ss}", - "hashrate1m", suffix1, - "hashrate5m", suffix5, - "hashrate15m", suffix15, - "hashrate1hr", suffix60, - "hashrate6hr", suffix360, - "hashrate1d", suffix1440, - "hashrate7d", suffix10080); - s = json_dumps(val, JSON_NO_UTF8 | JSON_PRESERVE_ORDER); - json_decref(val); - LOGNOTICE("Pool:%s", s); - fprintf(fp, "%s\n", s); - dealloc(s); - - JSON_CPACK(val, "{sf,sf,sf,sf}", - "SPS1m", sps1, - "SPS5m", sps5, - "SPS15m", sps15, - "SPS1h", sps60); - s = json_dumps(val, JSON_NO_UTF8 | JSON_PRESERVE_ORDER); - json_decref(val); - LOGNOTICE("Pool:%s", s); - fprintf(fp, "%s\n", s); - dealloc(s); - fclose(fp); - ck_rlock(&sdata->instance_lock); HASH_ITER(hh, sdata->stratum_instances, client, tmp) { if (!client->authorised) @@ -3582,6 +3533,7 @@ static void *statsupdate(void *arg) decay_time(&client->dsps60, 0, per_tdiff, 3600); decay_time(&client->dsps1440, 0, per_tdiff, 86400); decay_time(&client->dsps10080, 0, per_tdiff, 604800); + idle_workers++; if (per_tdiff > 600) client->idle = true; continue; @@ -3687,6 +3639,81 @@ static void *statsupdate(void *arg) } ck_runlock(&sdata->instance_lock); + ghs1 = stats->dsps1 * nonces; + suffix_string(ghs1, suffix1, 16, 0); + sps1 = stats->sps1; + + bias = !CKP_STANDALONE(ckp) ? 1.0 : time_bias(tdiff, 300); + ghs5 = stats->dsps5 * nonces / bias; + sps5 = stats->sps5 / bias; + suffix_string(ghs5, suffix5, 16, 0); + + bias = !CKP_STANDALONE(ckp) ? 1.0 : time_bias(tdiff, 900); + ghs15 = stats->dsps15 * nonces / bias; + suffix_string(ghs15, suffix15, 16, 0); + sps15 = stats->sps15 / bias; + + bias = !CKP_STANDALONE(ckp) ? 1.0 : time_bias(tdiff, 3600); + ghs60 = stats->dsps60 * nonces / bias; + sps60 = stats->sps60 / bias; + suffix_string(ghs60, suffix60, 16, 0); + + bias = !CKP_STANDALONE(ckp) ? 1.0 : time_bias(tdiff, 21600); + ghs360 = stats->dsps360 * nonces / bias; + suffix_string(ghs360, suffix360, 16, 0); + + bias = !CKP_STANDALONE(ckp) ? 1.0 : time_bias(tdiff, 86400); + ghs1440 = stats->dsps1440 * nonces / bias; + suffix_string(ghs1440, suffix1440, 16, 0); + + bias = !CKP_STANDALONE(ckp) ? 1.0 : time_bias(tdiff, 604800); + ghs10080 = stats->dsps10080 * nonces / bias; + suffix_string(ghs10080, suffix10080, 16, 0); + + snprintf(fname, 511, "%s/pool/pool.status", ckp->logdir); + fp = fopen(fname, "we"); + if (unlikely(!fp)) + LOGERR("Failed to fopen %s", fname); + + JSON_CPACK(val, "{si,si,si,si,si,si}", + "runtime", diff.tv_sec, + "Users", stats->users, + "Workers", stats->workers, + "Idle", idle_workers, + "Disconnected", stats->disconnected, + "Dead", stats->dead); + s = json_dumps(val, JSON_NO_UTF8 | JSON_PRESERVE_ORDER); + json_decref(val); + LOGNOTICE("Pool:%s", s); + fprintf(fp, "%s\n", s); + dealloc(s); + + JSON_CPACK(val, "{ss,ss,ss,ss,ss,ss,ss}", + "hashrate1m", suffix1, + "hashrate5m", suffix5, + "hashrate15m", suffix15, + "hashrate1hr", suffix60, + "hashrate6hr", suffix360, + "hashrate1d", suffix1440, + "hashrate7d", suffix10080); + s = json_dumps(val, JSON_NO_UTF8 | JSON_PRESERVE_ORDER); + json_decref(val); + LOGNOTICE("Pool:%s", s); + fprintf(fp, "%s\n", s); + dealloc(s); + + JSON_CPACK(val, "{sf,sf,sf,sf}", + "SPS1m", sps1, + "SPS5m", sps5, + "SPS15m", sps15, + "SPS1h", sps60); + s = json_dumps(val, JSON_NO_UTF8 | JSON_PRESERVE_ORDER); + json_decref(val); + LOGNOTICE("Pool:%s", s); + fprintf(fp, "%s\n", s); + dealloc(s); + fclose(fp); + ts_realtime(&ts_now); sprintf(cdfield, "%lu,%lu", ts_now.tv_sec, ts_now.tv_nsec); JSON_CPACK(val, "{ss,si,si,si,sf,sf,sf,sf,ss,ss,ss,ss}",