From 4168194bd0ba5696aa314f03777969fa3b33bfae Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 20 Jun 2014 21:40:56 +1000 Subject: [PATCH] Show per client connected stats instead of per user, every 10 mins --- src/stratifier.c | 129 ++++++++++++++++++++++++----------------------- 1 file changed, 66 insertions(+), 63 deletions(-) diff --git a/src/stratifier.c b/src/stratifier.c index 783aa9a3..b52b3050 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -48,6 +48,9 @@ struct pool_stats { int64_t unaccounted_shares; int64_t accounted_shares; + /* Cycle of 24 to determine which users to dump stats on */ + uint8_t userstats_cycle; + /* Shares per second for 1/5/15/60 minute rolling averages */ double sps1; double sps5; @@ -193,17 +196,6 @@ struct user_instance { char username[128]; int id; - tv_t last_share; - time_t last_stats; - time_t start_time; - - double dsps1; - double dsps5; - double dsps15; - double dsps60; - double dsps360; - double dsps1440; - int workers; }; @@ -224,13 +216,18 @@ struct stratum_instance { int64_t diff; /* Current diff */ int64_t old_diff; /* Previous diff */ int64_t diff_change_job_id; /* Last job_id we changed diff */ - double dsps5; /* Diff shares per second, 5 minute rolling average */ + double dsps1; /* Diff shares per second, 1 minute rolling average */ + double dsps5; /* ... 5 minute ... */ + double dsps60;/* etc */ + double dsps1440; tv_t ldc; /* Last diff change */ int ssdc; /* Shares since diff change */ tv_t first_share; tv_t last_share; + time_t start_time; bool authorised; + bool idle; user_instance_t *user_instance; char *useragent; @@ -1113,13 +1110,9 @@ static user_instance_t *authorise_user(const char *workername) ck_ilock(&instance_lock); HASH_FIND_STR(user_instances, username, instance); if (!instance) { - ts_t now; - /* New user instance */ instance = ckzalloc(sizeof(user_instance_t)); strcpy(instance->username, username); - ts_realtime(&now); - instance->start_time = now.tv_sec; ck_ulock(&instance_lock); instance->id = user_instance_id++; @@ -1183,6 +1176,7 @@ static json_t *parse_authorise(stratum_instance_t *client, json_t *params_val, j bool ret = false; const char *buf; int arr_size; + ts_t now; if (unlikely(!json_is_array(params_val))) { *err_val = json_string("params not an array"); @@ -1202,8 +1196,14 @@ static json_t *parse_authorise(stratum_instance_t *client, json_t *params_val, j *err_val = json_string("Empty workername parameter"); goto out; } + if (!memcmp(buf, ".", 1)) { + *err_val = json_string("Empty username parameter"); + goto out; + } client->user_instance = authorise_user(buf); client->user_id = client->user_instance->id; + ts_realtime(&now); + client->start_time = now.tv_sec; LOGNOTICE("Authorised client %d worker %s as user %s", client->id, buf, client->user_instance->username); @@ -1253,8 +1253,7 @@ static double sane_tdiff(tv_t *end, tv_t *start) return tdiff; } -static void add_submit(stratum_instance_t *client, user_instance_t *instance, int diff, - bool valid) +static void add_submit(stratum_instance_t *client, int diff, bool valid) { double tdiff, bdiff, dsps, drr, network_diff, bias; int64_t next_blockid, optimal; @@ -1267,16 +1266,15 @@ static void add_submit(stratum_instance_t *client, user_instance_t *instance, in network_diff = current_workbase->network_diff; ck_runlock(&workbase_lock); - tdiff = sane_tdiff(&now_t, &instance->last_share); + tdiff = sane_tdiff(&now_t, &client->last_share); if (unlikely(!client->first_share.tv_sec)) copy_tv(&client->first_share, &now_t); - decay_time(&instance->dsps1, diff, tdiff, 60); - decay_time(&instance->dsps5, diff, tdiff, 300); - decay_time(&instance->dsps15, diff, tdiff, 900); - decay_time(&instance->dsps60, diff, tdiff, 3600); - decay_time(&instance->dsps360, diff, tdiff, 21600); - decay_time(&instance->dsps1440, diff, tdiff, 86400); - copy_tv(&instance->last_share, &now_t); + decay_time(&client->dsps1, diff, tdiff, 60); + decay_time(&client->dsps5, diff, tdiff, 300); + decay_time(&client->dsps60, diff, tdiff, 3600); + decay_time(&client->dsps1440, diff, tdiff, 86400); + copy_tv(&client->last_share, &now_t); + client->idle = false; tdiff = sane_tdiff(&now_t, &client->last_share); copy_tv(&client->last_share, &now_t); @@ -1629,7 +1627,7 @@ out_unlock: } } else LOGINFO("Rejected client %d invalid share", client->id); - add_submit(client, client->user_instance, diff, result); + add_submit(client, diff, result); /* Log shares here */ len = strlen(logdir) + strlen(client->workername) + 12; @@ -2014,33 +2012,44 @@ static const double nonces = 4294967296; * avoid floods of stat data coming at once. */ static void update_userstats(ckpool_t *ckp) { - user_instance_t *instance, *tmp; + stratum_instance_t *client, *tmp; char cdfield[64]; time_t now_t; ts_t ts_now; json_t *val; + if (++stats.userstats_cycle > 0x1f) + stats.userstats_cycle = 0; + ts_realtime(&ts_now); sprintf(cdfield, "%lu,%lu", ts_now.tv_sec, ts_now.tv_nsec); now_t = ts_now.tv_sec; ck_rlock(&instance_lock); - HASH_ITER(hh, user_instances, instance, tmp) { + HASH_ITER(hh, stratum_instances, client, tmp) { double ghs1, ghs5, ghs60, ghs1440; + uint8_t cycle_mask; int elapsed; - if (instance->last_stats > now_t - 600) + /* Only show stats from clients that have returned shares in + * the last 10 minutes */ + if (client->idle) + continue; + /* Select clients using a mask to return each users's stats once + * every ~10 minutes */ + cycle_mask = client->user_id & 0x1f; + if (cycle_mask != stats.userstats_cycle) continue; - elapsed = now_t - instance->start_time; - instance->last_stats = now_t; - ghs1 = instance->dsps1 * nonces; - ghs5 = instance->dsps5 * nonces; - ghs60 = instance->dsps60 * nonces; - ghs1440 = instance->dsps1440 * nonces; - val = json_pack("{ss,si,ss,sf,sf,sf,sf,ss,ss,ss,ss}", + elapsed = now_t - client->start_time; + ghs1 = client->dsps1 * nonces; + ghs5 = client->dsps5 * nonces; + ghs60 = client->dsps60 * nonces; + ghs1440 = client->dsps1440 * nonces; + val = json_pack("{ss,si,si,ss,sf,sf,sf,sf,ss,ss,ss,ss}", "poolinstance", ckp->name, + "instanceid", client->id, "elapsed", elapsed, - "username", instance->username, + "username", client->user_instance->username, "hashrate", ghs1, "hashrate5m", ghs5, "hashrate1hr", ghs60, @@ -2069,7 +2078,7 @@ static void *statsupdate(void *arg) double ghs1, ghs5, ghs15, ghs60, ghs360, ghs1440, tdiff, bias; char suffix360[16], suffix1440[16]; double sps1, sps5, sps15, sps60; - user_instance_t *instance, *tmp; + stratum_instance_t *client, *tmp; char fname[512] = {}; tv_t now, diff; ts_t ts_now; @@ -2151,42 +2160,36 @@ static void *statsupdate(void *arg) fclose(fp); ck_rlock(&instance_lock); - HASH_ITER(hh, user_instances, instance, tmp) { + HASH_ITER(hh, stratum_instances, client, tmp) { bool idle = false; double ghs; - if (now.tv_sec - instance->last_share.tv_sec > 60) { + if (now.tv_sec - client->last_share.tv_sec > 60) { idle = true; /* No shares for over a minute, decay to 0 */ - decay_time(&instance->dsps1, 0, tdiff, 60); - decay_time(&instance->dsps5, 0, tdiff, 300); - decay_time(&instance->dsps15, 0, tdiff, 900); - decay_time(&instance->dsps60, 0, tdiff, 3600); - decay_time(&instance->dsps360, 0, tdiff, 21600); - decay_time(&instance->dsps1440, 0, tdiff, 86400); + decay_time(&client->dsps1, 0, tdiff, 60); + decay_time(&client->dsps5, 0, tdiff, 300); + decay_time(&client->dsps60, 0, tdiff, 3600); + decay_time(&client->dsps1440, 0, tdiff, 86400); + if (now.tv_sec - client->last_share.tv_sec > 600) + client->idle = true; } - ghs = instance->dsps1 * nonces; + ghs = client->dsps1 * nonces; suffix_string(ghs, suffix1, 16, 0); - ghs = instance->dsps5 * nonces; + ghs = client->dsps5 * nonces; suffix_string(ghs, suffix5, 16, 0); - ghs = instance->dsps15 * nonces; - suffix_string(ghs, suffix15, 16, 0); - ghs = instance->dsps60 * nonces; + ghs = client->dsps60 * nonces; suffix_string(ghs, suffix60, 16, 0); - ghs = instance->dsps360 * nonces; - suffix_string(ghs, suffix360, 16, 0); - ghs = instance->dsps1440 * nonces; + ghs = client->dsps1440 * nonces; suffix_string(ghs, suffix1440, 16, 0); - val = json_pack("{ss,ss,ss,ss,ss,ss}", + val = json_pack("{ss,ss,ss,ss}", "hashrate1m", suffix1, "hashrate5m", suffix5, - "hashrate15m", suffix15, "hashrate1hr", suffix60, - "hashrate6hr", suffix360, "hashrate1d", suffix1440); - snprintf(fname, 511, "%s/%s", ckp->logdir, instance->username); + snprintf(fname, 511, "%s/%s", ckp->logdir, client->workername); fp = fopen(fname, "w"); if (unlikely(!fp)) { LOGERR("Failed to fopen %s", fname); @@ -2197,7 +2200,7 @@ static void *statsupdate(void *arg) /* Only display the status of connected users to the * console log. */ if (!idle) - LOGNOTICE("User %s:%s", instance->username, s); + LOGNOTICE("Worker %s:%s", client->workername, s); dealloc(s); json_decref(val); fclose(fp); @@ -2221,10 +2224,10 @@ static void *statsupdate(void *arg) "createinet", "127.0.0.1"); ckdbq_add(ID_POOLSTATS, val); - /* Update stats 4 times per minute for smooth values, displaying + /* Update stats 3 times per minute for smooth values, displaying * status every minute. */ - for (i = 0; i < 4; i++) { - cksleep_ms_r(&stats.last_update, 15000); + for (i = 0; i < 3; i++) { + cksleep_ms_r(&stats.last_update, 20000); cksleep_prepare_r(&stats.last_update); update_userstats(ckp);