Skip to content

fix(buckyd): backfill a metric that appeared mid-copy - #58

Merged
deniszh merged 2 commits into
masterfrom
dzhdanov/500-fix
Sep 4, 2026
Merged

deniszh merged 2 commits into
masterfrom
dzhdanov/500-fix

Conversation

@deniszh

@deniszh deniszh commented Sep 4, 2026

Copy link
Copy Markdown
Member

A rebalance was failing with:

Error: Copying [10.211.134.3:4242]->[10.214.27.71:4242]:carbon.minutely.…
returned status code: 500  Body: file already exists

healMetric picks between backfilling and creating from a stat of the destination, then downloads or dumps the body before writing. On a host running go-carbon the metric can be created in that window, and go-whisper's CreateWithOptions refuses to overwrite an existing file — so CompressTo returns a bare os.ErrExist, the POST 500s, and rebalance retries the same losing race.

The destination does exist after all, and the dump on disk is exactly what the backfill path wants, so fill into the file that appeared instead of failing. The fallback reports its time under Fill rather than Compress, so it is visible in the response stats.

Not related to the out-of-order sidecar work: that only touched GET and DELETE, and every error it returns is wrapped with a prefix.

Left alone: the raw-copy branch below has the same race with a quieter outcome (os.Create truncates what go-carbon just wrote). It streams the body straight to the destination and has no dump to fill from.

Test: TestCompressMetricFillsFileThatAppeared pre-creates the compressed destination, then asserts the fallback ran and both source points arrived. go test ./cmd/buckyd/ passes; cmd/bucky-pickle-relay fails on master already (missing testing/data/gentests.py fixtures).

healMetric decides between backfilling and creating from a stat of the
destination, then downloads or dumps the body before it writes.  On a host
running go-carbon the metric can be created in that window, and go-whisper's
CreateWithOptions refuses to overwrite an existing file, so CompressTo returns
os.ErrExist and the copy fails with a 500 whose body is the bare "file already
exists" -- rebalance then retries the same losing race.

Treat that as what it is: the destination exists after all.  The dump on disk
is exactly what the backfill path wants, so fill into the file that appeared
instead of failing.  Stats report it under Fill rather than Compress, which is
also how the fallback shows up in a response.

The raw-copy branch below has the same race with a quieter outcome -- os.Create
truncates whatever go-carbon just wrote -- and is left alone; it streams the
body straight to the destination and has no dump to fill from.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The change is small and targeted with a regression test; only a minor improvement to error wrapping remains.

Pull request overview

This PR hardens buckyd’s metric-healing copy path against a race where the destination whisper file is created mid-copy (by go-carbon), causing CompressTo to fail with os.ErrExist and the request to 500/retry unnecessarily. It introduces a fallback that backfills into the newly-created destination file instead of treating the race as a hard error, and adds a regression test.

Changes:

  • Refactors the “dump then compress” branch in healMetric to use a new compressMetric helper that falls back to fill.All(...) on os.ErrExist.
  • Records fallback time under Fill (rather than Compress) to make the behavior visible in response stats.
  • Adds TestCompressMetricFillsFileThatAppeared to validate the race fallback and data arrival.
File summaries
File Description
cmd/buckyd/metrics.go Adds compressMetric helper and uses it from healMetric to backfill instead of failing when the destination appears mid-compress.
cmd/buckyd/compress_test.go Adds a regression test that pre-creates a compressed destination and asserts compressMetric performs the backfill fallback and preserves points.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread cmd/buckyd/metrics.go
@timtofan timtofan removed their assignment Sep 4, 2026
@timtofan
timtofan self-requested a review September 4, 2026 12:24
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@deniszh
deniszh merged commit 5ca7d75 into master Sep 4, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants