modernize UI - #2
Conversation
e331839 to
601634a
Compare
|
Hopefully addresses your feedback. Also added a historical chart of hashrate. |
| return 0; | ||
| } | ||
|
|
||
| /* downsample if needed */ |
There was a problem hiding this comment.
Stats are computed after this decimation. Seeded a 24h series of 100.0 Th/s with a single 999.0 spike at index 5 (the decimator keeps 0, 12, 24, ...); the dashboard reported Avg: 99.17 - Peak: 100.00. Moving the loop at :295 above this block fixes both figures.
| if (hr_count < DATUM_HR_HISTORY_SAMPLES) hr_count++; | ||
| dirty = 1; | ||
|
|
||
| /* persist every sample (60s) — small file, safe */ |
There was a problem hiding this comment.
Measured 1,507,856 bytes, mtime advancing exactly 60s with the size constant, zero miners connected. That is 2.02 GB/day of writes. Dropping clients[] takes it to 23 KB.
| static double total_th[DATUM_HR_HISTORY_SAMPLES]; | ||
| static int hr_head = 0; /* next write index */ | ||
| static int hr_count = 0; | ||
| static hr_client_t clients[DATUM_HR_MAX_CLIENTS]; |
There was a problem hiding this comment.
No reachable reader: all three render_svg call sites pass client_key = NULL, and render_sparkline lost its last caller in 11a146e. This is 1.44 MB of the 1.48 MB file.
| double *out_current, double *out_avg, double *out_peak); | ||
|
|
||
| /* Compact sparkline SVG for table cells */ | ||
| size_t datum_hashrate_hist_render_sparkline(char *out, size_t out_sz, |
There was a problem hiding this comment.
Dead since 11a146e removed the per-row chart: no source references, and no call sites in the linked binary.
| } | ||
| } | ||
|
|
||
| void datum_hashrate_hist_shutdown(void) { |
There was a problem hiding this comment.
No callers, so dirty (:42, :121, :189) is only ever read here at :241, making it write-only in practice. The save at :192 runs unconditionally every tick regardless.
| uint32_t magic = HR_MAGIC, ver = HR_VERSION; | ||
| int i; | ||
| if (!hr_path[0]) return; | ||
| f = fopen(hr_path, "wb"); |
There was a problem hiding this comment.
"wb" truncates in place, so a crash mid-write leaves a short file behind a valid magic/version header. Truncated the file inside total_th and restarted: all 1440 samples silently dropped, with no load line, no warning, and no diagnostic of any kind.
|
|
||
| static void make_client_key(char *key, size_t key_sz, T_DATUM_MINER_DATA *m, int tid, int cid) { | ||
| if (m && m->last_auth_username[0]) { | ||
| snprintf(key, key_sz, "%s", m->last_auth_username); |
There was a problem hiding this comment.
-Wformat-truncation on a clean build: 192 bytes into 64, so keys truncate at 63 chars against a 62-char bech32m address.
| for (i = 0; i < n; i++) { | ||
| double x = pad_l + (n == 1 ? plot_w / 2.0 : (double)i * plot_w / (double)(n - 1)); | ||
| double y = pad_t + plot_h - (vals[i] / vmax) * plot_h; | ||
| psz += snprintf(path + psz, sizeof(path) - psz, "%s%.1f,%.1f", i ? " L" : "M", x, y); |
There was a problem hiding this comment.
With one sample this emits d="M378.0,172.0" against fill="none". Rendered it: 0 pixels differ from blank, versus 244 for a two-point path. Fresh installs show an empty chart for the first two minutes.
| .required = false, .ptr = datum_config.mining_pow_algorithm, .default_string[0] = "auto", .max_string_len = sizeof(datum_config.mining_pow_algorithm) }, | ||
| { .var_type = DATUM_CONF_STRING, .category = "mining", .name = "hashrate_history_file", .description = "Path to file for persisting hashrate history samples (empty disables disk persistence)", | ||
| .example_default = true, | ||
| .required = false, .ptr = datum_config.mining_hashrate_history_file, .default_string[0] = "datum_hashrate_history.bin", .max_string_len = sizeof(datum_config.mining_hashrate_history_file) }, |
There was a problem hiding this comment.
Non-empty default means this is on by default writing to CWD, unlike save_submitblocks_dir which defaults to empty. Pointed it at an unwritable path: cannot write ... No such file or directory repeats every 60s with no suppression.
| const char *next_dir = (active && dir_mul > 0) ? "desc" : "asc"; | ||
| const char *cls = active ? (dir_mul > 0 ? "sortable sort-asc" : "sortable sort-desc") : "sortable"; | ||
| sz += snprintf(&output[sz], max_sz - 1 - sz, | ||
| "<TD class=\"%s\"><a href=\"/clients?sort=%s&dir=%s\"><U>%s</U></a></TD>", |
There was a problem hiding this comment.
Sort links drop hr_range (confirmed in the served HTML, all 11 carry only sort/dir), so clicking any column header resets the chart to 24h.
|
Related, not competing: OCEAN-xyz#230 makes the stylesheet replaceable at runtime (api.custom_css_file) without touching the templates, so it lands on either side of this PR. It applies to this fork's master clean. |

Some images from the new design
AI disclosure - all code written by Grok, tested by human on x86_64 Linux only.