refactor(daemon): share the output ring-window helper

The embedded daemon and the xmrig manager each kept their own copy of
the console output ring: append new bytes, trim the front to a cap at a
newline boundary, and hand a reader everything since its offset. The two
copies had drifted. The daemon tracked an absolute byte total so a
reader's offset stayed valid across a front-trim, while the miner keyed
its reader off the live buffer size, so a trim could silently rewind the
console feed.

- The append/trim and the since-offset logic now live in one small
  header, outputWindowSince and appendBounded, included by both. The
  trim keeps the newline-boundary cut and the guard that stops a lone
  trailing newline from erasing the whole buffer.
- The xmrig manager now carries the same absolute byte total, so its
  reader resolves against the window the same way and survives a trim
  (and a process restart that clears the buffer but keeps the total).

Tests cover feeding the ring well past the trim point while a reader
polls each chunk (the feed is continuous and never dies at the trim),
the lone-trailing-newline guard, and a cleared buffer with a retained
total.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-10-14 06:26:13 -05:00
co-authored by Claude Opus 4.8
parent e77b960cc5
commit e9042f091e
6 changed files with 85 additions and 39 deletions
+1 -11
View File
@@ -613,17 +613,7 @@ void XmrigManager::drainOutput() {
void XmrigManager::appendOutput(const char* data, size_t len) {
// Caller must hold output_mutex_
static constexpr size_t MAX_OUTPUT = 1024 * 1024; // 1 MB cap
process_output_.append(data, len);
if (process_output_.size() > MAX_OUTPUT) {
// Trim from the front at a newline boundary
size_t cut = process_output_.size() - MAX_OUTPUT;
auto pos = process_output_.find('\n', cut);
if (pos != std::string::npos)
process_output_.erase(0, pos + 1);
else
process_output_.erase(0, cut);
}
appendBounded(process_output_, output_total_, data, len, 1024 * 1024); // 1 MB cap (1.25x hysteresis)
}
std::vector<std::string> XmrigManager::getRecentLines(int maxLines) const {