diff --git a/html/green.png b/html/green.png new file mode 100644 index 00000000..42abda87 Binary files /dev/null and b/html/green.png differ diff --git a/html/orange.png b/html/orange.png new file mode 100644 index 00000000..c367f4af Binary files /dev/null and b/html/orange.png differ diff --git a/html/red.png b/html/red.png new file mode 100644 index 00000000..d32e13b5 Binary files /dev/null and b/html/red.png differ diff --git a/pool/page.php b/pool/page.php index 2873560c..ade9e803 100644 --- a/pool/page.php +++ b/pool/page.php @@ -287,7 +287,55 @@ function pgtop($info, $dotop, $user, $douser) $top .= '
'; if ($dotop === true) { + $lh = ''; $ls = ''; $lw = ''; + if (isset($info['now']) && isset($info['lastsh']) + && isset($info['lasthb']) && isset($info['lastwi'])) + { + $lsn = $info['now'] - $info['lastsh']; + $lhn = $info['now'] - $info['lasthb']; + $lwn = $info['now'] - $info['lastwi']; + if ($lsn < 2) + $lsc = 'green'; + else + { + if ($lsn < 4) + $lsc = 'orange'; + else + $lsc = 'red'; + } + if ($lhn < 3) + $lhc = 'green'; + else + { + if ($lhn < 6) + $lhc = 'orange'; + else + $lhc = 'red'; + } + if ($lwn < 36) + $lwc = 'green'; + else + { + if ($lwn < 46) + $lwc = 'orange'; + else + $lwc = 'red'; + } +$lsc = 'green'; +$lhc = 'orange'; +$lwc = 'red'; + $img1 = ' 10 || wqgot > 1000) { + if ((time(NULL) - now) > 10 || wqgot > 10000) { PQfinish(conn); conn = dbconnect(); now = time(NULL); @@ -4056,6 +4081,8 @@ int main(int argc, char **argv) ckp.main.ckp = &ckp; ckp.main.processname = strdup("main"); + cklock_init(&last_lock); + if (confirm_sharesummary) { // TODO: add a system lock to stop running 2 at once? confirm_summaries(); diff --git a/src/ckdb.h b/src/ckdb.h index 56272881..f4d43220 100644 --- a/src/ckdb.h +++ b/src/ckdb.h @@ -52,7 +52,7 @@ #define DB_VLOCK "1" #define DB_VERSION "0.9.6" -#define CKDB_VERSION DB_VERSION"-0.903" +#define CKDB_VERSION DB_VERSION"-0.910" #define WHERE_FFL " - from %s %s() line %d" #define WHERE_FFL_HERE __FILE__, __func__, __LINE__ @@ -197,6 +197,7 @@ enum data_type { TYPE_TV, TYPE_TVS, TYPE_CTV, + TYPE_FTV, TYPE_BLOB, TYPE_DOUBLE }; @@ -266,6 +267,14 @@ extern bool startup_complete; // Tell everyone to die extern bool everyone_die; +/* These are included in cmd_homepage + * to help identify when ckpool locks up (or dies) */ +extern tv_t last_heartbeat; +extern tv_t last_workinfo; +extern tv_t last_share; +extern tv_t last_auth; +extern cklock_t last_lock; + #define JSON_TRANSFER "json=" #define JSON_TRANSFER_LEN (sizeof(JSON_TRANSFER)-1) #define JSON_BEGIN '{' @@ -1558,6 +1567,7 @@ extern char *_data_to_buf(enum data_type typ, void *data, char *buf, size_t siz, #define int_to_buf(_data, _buf, _siz) _int_to_buf(_data, _buf, _siz, WHERE_FFL_HERE) #define tv_to_buf(_data, _buf, _siz) _tv_to_buf(_data, _buf, _siz, WHERE_FFL_HERE) #define ctv_to_buf(_data, _buf, _siz) _ctv_to_buf(_data, _buf, _siz, WHERE_FFL_HERE) +#define ftv_to_buf(_data, _buf, _siz) _ftv_to_buf(_data, _buf, _siz, WHERE_FFL_HERE) #define tvs_to_buf(_data, _buf, _siz) _tvs_to_buf(_data, _buf, _siz, WHERE_FFL_HERE) //#define blob_to_buf(_data, _buf, _siz) _blob_to_buf(_data, _buf, _siz, WHERE_FFL_HERE) #define double_to_buf(_data, _buf, _siz) _double_to_buf(_data, _buf, _siz, WHERE_FFL_HERE) @@ -1568,6 +1578,8 @@ extern char *_int_to_buf(int32_t data, char *buf, size_t siz, WHERE_FFL_ARGS); extern char *_tv_to_buf(tv_t *data, char *buf, size_t siz, WHERE_FFL_ARGS); // Convert tv to S,uS extern char *_ctv_to_buf(tv_t *data, char *buf, size_t siz, WHERE_FFL_ARGS); +// Convert tv to S.uS +extern char *_ftv_to_buf(tv_t *data, char *buf, size_t siz, WHERE_FFL_ARGS); // Convert tv to seconds (ignore uS) extern char *_tvs_to_buf(tv_t *data, char *buf, size_t siz, WHERE_FFL_ARGS); /* unused yet diff --git a/src/ckdb_cmd.c b/src/ckdb_cmd.c index 08001bdf..f957fd8c 100644 --- a/src/ckdb_cmd.c +++ b/src/ckdb_cmd.c @@ -1823,6 +1823,11 @@ static char *cmd_sharelog(PGconn *conn, char *cmd, char *id, if (workinfoid == -1) { LOGERR("%s(%s) %s.failed.DBE", __func__, cmd, id); return strdup("failed.DBE"); + } else { + // Only flag a successful workinfo + ck_wlock(&last_lock); + setnow(&last_workinfo); + ck_wunlock(&last_lock); } LOGDEBUG("%s.ok.added %"PRId64, id, workinfoid); wiconf: @@ -1909,6 +1914,11 @@ wiconf: if (!ok) { LOGERR("%s(%s) %s.failed.DATA", __func__, cmd, id); return strdup("failed.DATA"); + } else { + // Only flag a successful share + ck_wlock(&last_lock); + setnow(&last_share); + ck_wunlock(&last_lock); } LOGDEBUG("%s.ok.added %s", id, transfer_data(i_nonce)); sconf: @@ -2237,8 +2247,12 @@ static char *cmd_auth_do(PGconn *conn, char *cmd, char *id, char *by, if (!ok) { LOGDEBUG("%s() %s.failed.DBE", __func__, id); return strdup("failed.DBE"); + } else { + // Only flag a successful auth + ck_wlock(&last_lock); + setnow(&last_auth); + ck_wunlock(&last_lock); } - snprintf(reply, siz, "ok.authorise={\"secondaryuserid\":\"%s\"," "\"difficultydefault\":%d}", @@ -2321,8 +2335,12 @@ static char *cmd_addrauth_do(PGconn *conn, char *cmd, char *id, char *by, if (!ok) { LOGDEBUG("%s() %s.failed.DBE", __func__, id); return strdup("failed.DBE"); + } else { + // Only flag a successful auth + ck_wlock(&last_lock); + setnow(&last_auth); + ck_wunlock(&last_lock); } - snprintf(reply, siz, "ok.addrauth={\"secondaryuserid\":\"%s\"," "\"difficultydefault\":%d}", @@ -2367,6 +2385,10 @@ static char *cmd_heartbeat(__maybe_unused PGconn *conn, char *cmd, char *id, if (!startup_complete) goto pulse; + ck_wlock(&last_lock); + setnow(&last_heartbeat); + ck_wunlock(&last_lock); + K_WLOCK(heartbeatqueue_free); if (heartbeatqueue_store->count == 0) { K_WUNLOCK(heartbeatqueue_free); @@ -2413,7 +2435,7 @@ pulse: } static char *cmd_homepage(__maybe_unused PGconn *conn, char *cmd, char *id, - __maybe_unused tv_t *now, __maybe_unused char *by, + tv_t *now, __maybe_unused char *by, __maybe_unused char *code, __maybe_unused char *inet, __maybe_unused tv_t *notcd, K_TREE *trf_root) { @@ -2437,6 +2459,26 @@ static char *cmd_homepage(__maybe_unused PGconn *conn, char *cmd, char *id, APPEND_REALLOC_INIT(buf, off, len); APPEND_REALLOC(buf, off, len, "ok."); + + // N.B. cmd_homepage isn't called until startup_complete + ftv_to_buf(now, reply, siz); + snprintf(tmp, sizeof(tmp), "now=%s%c", reply, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + ck_wlock(&last_lock); + ftv_to_buf(&last_heartbeat, reply, siz); + snprintf(tmp, sizeof(tmp), "lasthb=%s%c", reply, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + ftv_to_buf(&last_workinfo, reply, siz); + snprintf(tmp, sizeof(tmp), "lastwi=%s%c", reply, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + ftv_to_buf(&last_share, reply, siz); + snprintf(tmp, sizeof(tmp), "lastsh=%s%c", reply, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + ftv_to_buf(&last_auth, reply, siz); + ck_wunlock(&last_lock); + snprintf(tmp, sizeof(tmp), "lastau=%s%c", reply, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + if (last_bc.tv_sec) { tvs_to_buf(&last_bc, reply, siz); snprintf(tmp, sizeof(tmp), "lastbc=%s%c", reply, FLDSEP); diff --git a/src/ckdb_data.c b/src/ckdb_data.c index 1139f8fc..d8ef8b38 100644 --- a/src/ckdb_data.c +++ b/src/ckdb_data.c @@ -358,6 +358,7 @@ void _txt_to_double(char *nam, char *fld, double *data, size_t siz, WHERE_FFL_AR char *_data_to_buf(enum data_type typ, void *data, char *buf, size_t siz, WHERE_FFL_ARGS) { struct tm tm; + double d; if (!buf) { switch (typ) { @@ -376,6 +377,7 @@ char *_data_to_buf(enum data_type typ, void *data, char *buf, size_t siz, WHERE_ siz = DATE_BUFSIZ; break; case TYPE_CTV: + case TYPE_FTV: siz = CDATE_BUFSIZ; break; case TYPE_DOUBLE: @@ -419,6 +421,11 @@ char *_data_to_buf(enum data_type typ, void *data, char *buf, size_t siz, WHERE_ (((tv_t *)data)->tv_sec), (((tv_t *)data)->tv_usec)); break; + case TYPE_FTV: + d = (double)(((tv_t *)data)->tv_sec) + + (double)(((tv_t *)data)->tv_usec) / 1000000.0; + snprintf(buf, siz, "%.6f", d); + break; case TYPE_TVS: snprintf(buf, siz, "%ld", (((tv_t *)data)->tv_sec)); break; @@ -456,6 +463,12 @@ char *_ctv_to_buf(tv_t *data, char *buf, size_t siz, WHERE_FFL_ARGS) return _data_to_buf(TYPE_CTV, (void *)data, buf, siz, WHERE_FFL_PASS); } +// Convert tv to S.uS +char *_ftv_to_buf(tv_t *data, char *buf, size_t siz, WHERE_FFL_ARGS) +{ + return _data_to_buf(TYPE_FTV, (void *)data, buf, siz, WHERE_FFL_PASS); +} + // Convert tv to seconds (ignore uS) char *_tvs_to_buf(tv_t *data, char *buf, size_t siz, WHERE_FFL_ARGS) {