Skip to content

fix: keep history responsive during archive work - #1271

Merged
frahlg merged 4 commits into
masterfrom
fix/archive-read-handoff-1270
Sep 14, 2026
Merged

frahlg merged 4 commits into
masterfrom
fix/archive-read-handoff-1270

Conversation

@frahlg

@frahlg frahlg commented Sep 14, 2026

Copy link
Copy Markdown
Member

Problem and result

A completed hourly chart can time out when its partial boundary hours wait behind archive staging and compression (#1270). Reads now share a separate lock with file publication and raw pruning. Building and checking an archive no longer excludes those reads. The SQLite-to-Parquet handover stays consistent, and raw values still win when a correction arrives after the archive copy.

Archive writes use short transactions on a reserved SQLite connection with immediate busy errors. They release both locks before retrying, yield to the live queue, and prune at most 64 copied keys per transaction, with smaller retries after a deadline. Dense-hour preparation reads a SQLite snapshot outside the writer locks and the short write budget. If live data changes, the snapshot upgrade fails and the whole preparation retries before the summary can commit. The connection's previous busy timeout is restored before reuse. Live commits honor cancellation while waiting for their mutex and retry temporary SQLite contention promptly without discarding accepted ticks.

Scope and safety

Storage code and synthetic tests only; no schema, API, driver or UI changes. File readback, hashes, sync, atomic rename and copied-key/value checks remain in place. PR #1261 also touches store.go; this PR changes only its archive mutex fields and leaves that PR's backup work alone.

The existing finite queue still rejects overflow explicitly during a prolonged storage outage. The tests establish progress under bounded contention; they do not promise unlimited buffering or prove Raspberry Pi disk latency. Keep #1270 open as a release-blocker until the published beta passes the large-backlog chart checks on hardware.

Verification

  • make verify passed locally, including Go tests, vet, builds, Compose checks, release checks and the bundled Energyplan worker.
  • Nine synthetic concurrency regressions passed three times with go test -race.
  • The same nine regressions passed on an ARM64 Raspberry Pi using isolated synthetic databases.
  • The partial-hour regression failed with a deadline on the unchanged base and passes with this fix.
  • Coverage includes slow Parquet staging, exact boundary values, reader/pruner overlap, late corrections, canceled publication/removal, external SQLite write contention, bounded slow archive transactions, restored connection settings and accepted-tick readback. A dense-hour regression exceeds the write deadline during preparation and verifies that a concurrent raw insert survives the retry. A separate test verifies that an inner write deadline retries within the same parent archive job.

Reproduce the focused suite from go/:

go test -race ./internal/state -run 'TestPartialHour|TestArchivePruneKeeps|TestArchivePublication|TestArchiveSQLiteBusy|TestSlowArchive|TestSlowParquetStaging|TestHistoryBatchLockWait|TestDenseArchiveHour|TestPreparedArchiveHour' -count=3

No release or hardware installation is part of these test results. Physical EV charging remains untested in this change.

Checklist

  • The change follows VISION.md and one selected scope.
  • I checked overlapping PRs and coordinated shared files/contracts.
  • Relevant checks cover the changed behaviour and failure paths.
  • A human reviewed changed UI in a browser, or no UI changed.
  • A Changeset is included, or the change is exempt.
  • Every commit has a DCO sign-off.

Signed-off-by: Fredrik Ahlgren <fredrik@sourceful-labs.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 14, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-14T17:25:02.142325Z d51a710 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

Signed-off-by: Fredrik Ahlgren <fredrik@sourceful-labs.com>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d51a710129

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread go/internal/state/archive_write.go Outdated
Comment on lines +23 to +24
if !historyWriteBusy(err) {
return err

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Retry archive work after the per-attempt deadline

When mergeArchivedHour legitimately takes more than one second—for example, while scanning a dense hour on a slow target disk—tryArchiveBatch returns context.DeadlineExceeded, but this branch treats every non-SQLite-busy error as terminal. Unlike pruning, the hourly merge does not reduce or otherwise resume its work, and its Parquet receipt is written only after the entire file completes, so runSeriesHourBackfill repeatedly restages and restarts the same file without ever becoming ready. Retry this inner deadline after releasing the locks while the parent work budget remains valid, or make the merge resumable.

Useful? React with 👍 / 👎.

Signed-off-by: Fredrik Ahlgren <fredrik@sourceful-labs.com>
Signed-off-by: Fredrik Ahlgren <fredrik@sourceful-labs.com>
@frahlg
frahlg merged commit e01ac3d into master Sep 14, 2026
16 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.

1 participant