Browse Source

ckdb - add the ckpool workerstats command

master
kanoi 10 years ago
parent
commit
c3bca3e3b0
  1. 24
      src/ckdb.c
  2. 9
      src/ckdb.h
  3. 74
      src/ckdb_cmd.c
  4. 84
      src/ckdb_dbio.c

24
src/ckdb.c

@ -1778,10 +1778,10 @@ static void summarise_userstats()
K_ITEM *first, *last, *new, *next, *tmp; K_ITEM *first, *last, *new, *next, *tmp;
USERSTATS *userstats, *us_first, *us_last, *us_next; USERSTATS *userstats, *us_first, *us_last, *us_next;
double statrange, factor; double statrange, factor;
bool locked, upgrade; bool locked, upgrade, issix, sixdiff;
tv_t now, process, when; tv_t now, process, when;
PGconn *conn = NULL; PGconn *conn = NULL;
int count; int count, sixcount;
char error[1024]; char error[1024];
char tvbuf1[DATE_BUFSIZ], tvbuf2[DATE_BUFSIZ]; char tvbuf1[DATE_BUFSIZ], tvbuf2[DATE_BUFSIZ];
@ -1838,6 +1838,8 @@ static void summarise_userstats()
next = next_in_ktree(ctx); next = next_in_ktree(ctx);
upgrade = true; upgrade = true;
issix = us_first->six;
sixdiff = false;
K_ULOCK(userstats_free); K_ULOCK(userstats_free);
new = k_unlink_head(userstats_free); new = k_unlink_head(userstats_free);
DATA_USERSTATS(userstats, new); DATA_USERSTATS(userstats, new);
@ -1850,6 +1852,7 @@ static void summarise_userstats()
k_add_head(userstats_summ, first); k_add_head(userstats_summ, first);
count = 1; count = 1;
sixcount = issix ? 1 : 0;
while (next) { while (next) {
DATA_USERSTATS(us_next, next); DATA_USERSTATS(us_next, next);
statrange = tvdiff(&when, &(us_next->statsdate)); statrange = tvdiff(&when, &(us_next->statsdate));
@ -1861,7 +1864,10 @@ static void summarise_userstats()
if (us_next->summarylevel[0] == SUMMARY_NONE && if (us_next->summarylevel[0] == SUMMARY_NONE &&
us_next->userid == userstats->userid && us_next->userid == userstats->userid &&
strcmp(us_next->workername, userstats->workername) == 0) { strcmp(us_next->workername, userstats->workername) == 0) {
if (us_next->six != issix)
sixdiff = true;
count++; count++;
sixcount += us_next->six ? 1 : 0;
userstats->hashrate += us_next->hashrate; userstats->hashrate += us_next->hashrate;
userstats->hashrate5m += us_next->hashrate5m; userstats->hashrate5m += us_next->hashrate5m;
userstats->hashrate1hr += us_next->hashrate1hr; userstats->hashrate1hr += us_next->hashrate1hr;
@ -1870,8 +1876,10 @@ static void summarise_userstats()
userstats->elapsed = us_next->elapsed; userstats->elapsed = us_next->elapsed;
userstats->summarycount += us_next->summarycount; userstats->summarycount += us_next->summarycount;
userstats_root = remove_from_ktree(userstats_root, next, cmp_userstats); userstats_root = remove_from_ktree(userstats_root,
userstats_statsdate_root = remove_from_ktree(userstats_statsdate_root, next, next, cmp_userstats);
userstats_statsdate_root = remove_from_ktree(userstats_statsdate_root,
next,
cmp_userstats_statsdate); cmp_userstats_statsdate);
k_unlink_item(userstats_store, next); k_unlink_item(userstats_store, next);
k_add_head(userstats_summ, next); k_add_head(userstats_summ, next);
@ -1895,8 +1903,14 @@ static void summarise_userstats()
userstats->summarylevel[0] = SUMMARY_DB; userstats->summarylevel[0] = SUMMARY_DB;
userstats->summarylevel[1] = '\0'; userstats->summarylevel[1] = '\0';
if (issix && !sixdiff) {
// Expect 6 per poolinstance // Expect 6 per poolinstance
factor = (double)count / 6.0; factor = (double)count / 6.0;
} else {
// For now ... new format is still 6 per hour
factor = (double)count / 6.0;
}
userstats->hashrate *= factor; userstats->hashrate *= factor;
userstats->hashrate5m *= factor; userstats->hashrate5m *= factor;
userstats->hashrate1hr *= factor; userstats->hashrate1hr *= factor;
@ -2434,6 +2448,7 @@ static void *socketer(__maybe_unused void *arg)
case CMD_SHARELOG: case CMD_SHARELOG:
case CMD_POOLSTAT: case CMD_POOLSTAT:
case CMD_USERSTAT: case CMD_USERSTAT:
case CMD_WORKERSTAT:
case CMD_BLOCK: case CMD_BLOCK:
// First message from the pool // First message from the pool
if (want_first) { if (want_first) {
@ -2601,6 +2616,7 @@ static bool reload_line(PGconn *conn, char *filename, uint64_t count, char *buf)
case CMD_HEARTBEAT: case CMD_HEARTBEAT:
case CMD_POOLSTAT: case CMD_POOLSTAT:
case CMD_USERSTAT: case CMD_USERSTAT:
case CMD_WORKERSTAT:
case CMD_BLOCK: case CMD_BLOCK:
if (confirm_sharesummary) if (confirm_sharesummary)
break; break;

9
src/ckdb.h

@ -52,7 +52,7 @@
#define DB_VLOCK "1" #define DB_VLOCK "1"
#define DB_VERSION "0.9.6" #define DB_VERSION "0.9.6"
#define CKDB_VERSION DB_VERSION"-0.744" #define CKDB_VERSION DB_VERSION"-0.750"
#define WHERE_FFL " - from %s %s() line %d" #define WHERE_FFL " - from %s %s() line %d"
#define WHERE_FFL_HERE __FILE__, __func__, __LINE__ #define WHERE_FFL_HERE __FILE__, __func__, __LINE__
@ -296,6 +296,7 @@ enum cmd_values {
CMD_WORKERSET, CMD_WORKERSET,
CMD_POOLSTAT, CMD_POOLSTAT,
CMD_USERSTAT, CMD_USERSTAT,
CMD_WORKERSTAT,
CMD_BLOCK, CMD_BLOCK,
CMD_BLOCKLIST, CMD_BLOCKLIST,
CMD_BLOCKSTATUS, CMD_BLOCKSTATUS,
@ -1173,6 +1174,7 @@ typedef struct userstats {
double hashrate1hr; double hashrate1hr;
double hashrate24hr; double hashrate24hr;
bool idle; // Non-db field bool idle; // Non-db field
bool six; // Non-db field
char summarylevel[TXT_FLAG+1]; // Initially SUMMARY_NONE in RAM char summarylevel[TXT_FLAG+1]; // Initially SUMMARY_NONE in RAM
int32_t summarycount; int32_t summarycount;
tv_t statsdate; tv_t statsdate;
@ -1772,6 +1774,11 @@ extern bool userstats_add(char *poolinstance, char *elapsed, char *username,
char *hashrate1hr, char *hashrate24hr, bool idle, char *hashrate1hr, char *hashrate24hr, bool idle,
bool eos, char *by, char *code, char *inet, tv_t *cd, bool eos, char *by, char *code, char *inet, tv_t *cd,
K_TREE *trf_root); K_TREE *trf_root);
extern bool workerstats_add(char *poolinstance, char *elapsed, char *username,
char *workername, char *hashrate, char *hashrate5m,
char *hashrate1hr, char *hashrate24hr, bool idle,
char *by, char *code, char *inet, tv_t *cd,
K_TREE *trf_root);
extern bool userstats_fill(PGconn *conn); extern bool userstats_fill(PGconn *conn);
extern bool markersummary_fill(PGconn *conn); extern bool markersummary_fill(PGconn *conn);
#define workmarkers_process(_conn, _add, _markerid, _poolinstance, \ #define workmarkers_process(_conn, _add, _markerid, _poolinstance, \

74
src/ckdb_cmd.c

@ -728,6 +728,79 @@ static char *cmd_userstats(__maybe_unused PGconn *conn, char *cmd, char *id,
return strdup(reply); return strdup(reply);
} }
static char *cmd_workerstats(__maybe_unused PGconn *conn, char *cmd, char *id,
__maybe_unused tv_t *notnow, char *by, char *code,
char *inet, tv_t *cd, K_TREE *trf_root)
{
char reply[1024] = "";
size_t siz = sizeof(reply);
// log to logfile
K_ITEM *i_poolinstance, *i_elapsed, *i_username, *i_workername;
K_ITEM *i_hashrate, *i_hashrate5m, *i_hashrate1hr, *i_hashrate24hr;
K_ITEM *i_idle;
bool ok = false, idle;
LOGDEBUG("%s(): cmd '%s'", __func__, cmd);
i_poolinstance = require_name(trf_root, "poolinstance", 1, NULL, reply, siz);
if (!i_poolinstance)
return strdup(reply);
i_elapsed = require_name(trf_root, "elapsed", 1, NULL, reply, siz);
if (!i_elapsed)
return strdup(reply);
i_username = require_name(trf_root, "username", 1, NULL, reply, siz);
if (!i_username)
return strdup(reply);
i_workername = require_name(trf_root, "workername", 1, NULL, reply, siz);
if (!i_workername)
return strdup(reply);
i_hashrate = require_name(trf_root, "hashrate", 1, NULL, reply, siz);
if (!i_hashrate)
return strdup(reply);
i_hashrate5m = require_name(trf_root, "hashrate5m", 1, NULL, reply, siz);
if (!i_hashrate5m)
return strdup(reply);
i_hashrate1hr = require_name(trf_root, "hashrate1hr", 1, NULL, reply, siz);
if (!i_hashrate1hr)
return strdup(reply);
i_hashrate24hr = require_name(trf_root, "hashrate24hr", 1, NULL, reply, siz);
if (!i_hashrate24hr)
return strdup(reply);
i_idle = require_name(trf_root, "idle", 1, NULL, reply, siz);
if (!i_idle)
return strdup(reply);
idle = (strcasecmp(transfer_data(i_idle), TRUE_STR) == 0);
ok = workerstats_add(transfer_data(i_poolinstance),
transfer_data(i_elapsed),
transfer_data(i_username),
transfer_data(i_workername),
transfer_data(i_hashrate),
transfer_data(i_hashrate5m),
transfer_data(i_hashrate1hr),
transfer_data(i_hashrate24hr),
idle, by, code, inet, cd, trf_root);
if (!ok) {
LOGERR("%s() %s.failed.DATA", __func__, id);
return strdup("failed.DATA");
}
LOGDEBUG("%s.ok.", id);
snprintf(reply, siz, "ok.");
return strdup(reply);
}
static char *cmd_blocklist(__maybe_unused PGconn *conn, char *cmd, char *id, static char *cmd_blocklist(__maybe_unused PGconn *conn, char *cmd, char *id,
__maybe_unused tv_t *now, __maybe_unused char *by, __maybe_unused tv_t *now, __maybe_unused char *by,
__maybe_unused char *code, __maybe_unused char *inet, __maybe_unused char *code, __maybe_unused char *inet,
@ -4126,6 +4199,7 @@ struct CMDS ckdb_cmds[] = {
{ CMD_WORKERSET,"workerset", false, false, cmd_workerset, ACCESS_WEB }, { CMD_WORKERSET,"workerset", false, false, cmd_workerset, ACCESS_WEB },
{ CMD_POOLSTAT, "poolstats", false, true, cmd_poolstats, ACCESS_POOL }, { CMD_POOLSTAT, "poolstats", false, true, cmd_poolstats, ACCESS_POOL },
{ CMD_USERSTAT, "userstats", false, true, cmd_userstats, ACCESS_POOL }, { CMD_USERSTAT, "userstats", false, true, cmd_userstats, ACCESS_POOL },
{ CMD_WORKERSTAT,"workerstats", false, true, cmd_workerstats,ACCESS_POOL },
{ CMD_BLOCK, "block", false, true, cmd_blocks, ACCESS_POOL }, { CMD_BLOCK, "block", false, true, cmd_blocks, ACCESS_POOL },
{ CMD_BLOCKLIST,"blocklist", false, false, cmd_blocklist, ACCESS_WEB }, { CMD_BLOCKLIST,"blocklist", false, false, cmd_blocklist, ACCESS_WEB },
{ CMD_BLOCKSTATUS,"blockstatus",false, false, cmd_blockstatus,ACCESS_WEB }, { CMD_BLOCKSTATUS,"blockstatus",false, false, cmd_blockstatus,ACCESS_WEB },

84
src/ckdb_dbio.c

@ -4686,6 +4686,7 @@ bool userstats_add(char *poolinstance, char *elapsed, char *username,
SIMPLEDATEINIT(row, cd, by, code, inet); SIMPLEDATEINIT(row, cd, by, code, inet);
SIMPLEDATETRANSFER(trf_root, row); SIMPLEDATETRANSFER(trf_root, row);
copy_tv(&(row->statsdate), &(row->createdate)); copy_tv(&(row->statsdate), &(row->createdate));
row->six = true;
if (eos) { if (eos) {
// Save it for end processing // Save it for end processing
@ -4788,6 +4789,89 @@ advancetogo:
return true; return true;
} }
// This is to RAM. The summariser calls the DB I/O functions for userstats
bool workerstats_add(char *poolinstance, char *elapsed, char *username,
char *workername, char *hashrate, char *hashrate5m,
char *hashrate1hr, char *hashrate24hr, bool idle,
char *by, char *code, char *inet, tv_t *cd,
K_TREE *trf_root)
{
K_ITEM *us_item, *u_item, *us_match, look;
USERSTATS *row, cmp, *match;
USERS *users;
K_TREE_CTX ctx[1];
LOGDEBUG("%s(): add", __func__);
K_WLOCK(userstats_free);
us_item = k_unlink_head(userstats_free);
K_WUNLOCK(userstats_free);
DATA_USERSTATS(row, us_item);
STRNCPY(row->poolinstance, poolinstance);
TXT_TO_BIGINT("elapsed", elapsed, row->elapsed);
K_RLOCK(users_free);
u_item = find_users(username);
K_RUNLOCK(users_free);
if (!u_item)
return false;
DATA_USERS(users, u_item);
row->userid = users->userid;
TXT_TO_STR("workername", workername, row->workername);
TXT_TO_DOUBLE("hashrate", hashrate, row->hashrate);
TXT_TO_DOUBLE("hashrate5m", hashrate5m, row->hashrate5m);
TXT_TO_DOUBLE("hashrate1hr", hashrate1hr, row->hashrate1hr);
TXT_TO_DOUBLE("hashrate24hr", hashrate24hr, row->hashrate24hr);
row->idle = idle;
row->summarylevel[0] = SUMMARY_NONE;
row->summarylevel[1] = '\0';
row->summarycount = 1;
SIMPLEDATEINIT(row, cd, by, code, inet);
SIMPLEDATETRANSFER(trf_root, row);
copy_tv(&(row->statsdate), &(row->createdate));
row->six = false;
// confirm_summaries() doesn't call this
if (reloading) {
memcpy(&cmp, row, sizeof(cmp));
INIT_USERSTATS(&look);
look.data = (void *)(&cmp);
// Just zero it to ensure the DB record is after it, not equal to it
cmp.statsdate.tv_usec = 0;
/* If there is a matching user+worker DB record summarising this row,
* or a matching user+worker DB record next after this row, discard it */
us_match = find_after_in_ktree(userstats_workerstatus_root, &look,
cmp_userstats_workerstatus, ctx);
DATA_USERSTATS_NULL(match, us_match);
if (us_match &&
match->userid == row->userid &&
strcmp(match->workername, row->workername) == 0 &&
match->summarylevel[0] != SUMMARY_NONE) {
K_WLOCK(userstats_free);
k_add_head(userstats_free, us_item);
K_WUNLOCK(userstats_free);
return true;
}
}
workerstatus_update(NULL, NULL, row);
K_WLOCK(userstats_free);
userstats_root = add_to_ktree(userstats_root, us_item, cmp_userstats);
userstats_statsdate_root = add_to_ktree(userstats_statsdate_root, us_item,
cmp_userstats_statsdate);
if (!startup_complete) {
userstats_workerstatus_root = add_to_ktree(userstats_workerstatus_root,
us_item,
cmp_userstats_workerstatus);
}
k_add_head(userstats_store, us_item);
K_WUNLOCK(userstats_free);
return true;
}
// TODO: data selection - only require ? // TODO: data selection - only require ?
bool userstats_fill(PGconn *conn) bool userstats_fill(PGconn *conn)
{ {

Loading…
Cancel
Save