The timestamp in a snapshot ID is in whole seconds. A snapshot create that started in the same second as the previous run of the same snapshot name built the same ID, and the insert into snapshots failed with UNIQUE constraint failed: snapshots.id. CreateSnapshotWithName now looks the ID up in the local index before inserting; if a snapshot already has it, it waits a second and builds the ID again. The ID format is unchanged, so docs/DATAMODEL.md needs no edit.
What a reader might trip over:
Judgement call: the create waits only when the ID is taken, not before every snapshot, so a normal backup is not delayed.
Deviation: the new test calls CreateSnapshotWithName twice instead of running two whole backups. Under -race on a loaded host a small backup takes over a second, and a test of two CreateSnapshot runs passed without the fix.
A failed run leaves an incomplete snapshot, which the next run deletes from the local index before creating its own. A retry within the same second therefore still gets the failed run's ID, as before this change.
The wait is a one-second time.Sleep that does not watch the context, so an interrupt during it takes effect up to a second later.
Model: opus-5-5
Fixes https://git.eeqj.de/sneak/vaultik/issues/270.
The timestamp in a snapshot ID is in whole seconds. A `snapshot create` that started in the same second as the previous run of the same snapshot name built the same ID, and the insert into `snapshots` failed with `UNIQUE constraint failed: snapshots.id`. `CreateSnapshotWithName` now looks the ID up in the local index before inserting; if a snapshot already has it, it waits a second and builds the ID again. The ID format is unchanged, so `docs/DATAMODEL.md` needs no edit.
What a reader might trip over:
- Judgement call: the create waits only when the ID is taken, not before every snapshot, so a normal backup is not delayed.
- Deviation: the new test calls `CreateSnapshotWithName` twice instead of running two whole backups. Under `-race` on a loaded host a small backup takes over a second, and a test of two `CreateSnapshot` runs passed without the fix.
- A failed run leaves an incomplete snapshot, which the next run deletes from the local index before creating its own. A retry within the same second therefore still gets the failed run's ID, as before this change.
- The wait is a one-second `time.Sleep` that does not watch the context, so an interrupt during it takes effect up to a second later.
Model: opus-5-5
clawbot
self-assigned this 2026-10-08 02:55:41 +02:00
The timestamp in a snapshot ID is in whole seconds, so a `snapshot
create` that started in the same second as the previous run of that
snapshot name got the same ID, and inserting its row failed with
`UNIQUE constraint failed: snapshots.id`. CreateSnapshotWithName now
looks the ID up in the local index first and, if it is taken, waits a
second and takes a new timestamp. The ID format is unchanged.
Only the local index is checked. That is where the insert fails, and
the process lock serializes runs, so nothing takes the ID between the
lookup and the insert.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Fixes #270.
The timestamp in a snapshot ID is in whole seconds. A
snapshot createthat started in the same second as the previous run of the same snapshot name built the same ID, and the insert intosnapshotsfailed withUNIQUE constraint failed: snapshots.id.CreateSnapshotWithNamenow looks the ID up in the local index before inserting; if a snapshot already has it, it waits a second and builds the ID again. The ID format is unchanged, sodocs/DATAMODEL.mdneeds no edit.What a reader might trip over:
CreateSnapshotWithNametwice instead of running two whole backups. Under-raceon a loaded host a small backup takes over a second, and a test of twoCreateSnapshotruns passed without the fix.time.Sleepthat does not watch the context, so an interrupt during it takes effect up to a second later.Model: opus-5-5
Review passed.
Model: opus-5-5