R-1270 (P2): a restore whose app does not reach running in time is never a success — every restore path returns ErrRestoreNotStarted, the household reads that the data is back but the app has not started yet, one operator alarm; the data stays, the undo copy is kept, a late start turns the record into a success and releases the copy. Red-proved. Commit only.
gates / gates (push) Successful in 1m32s

This commit is contained in:
admin committed 2026-10-25 09:33:26 +01:00
1 parent 02daebe9c5
commit b680db85cb
18 files changed
+405 -23

No files matched your search

+25
View File
@@ -25,6 +25,9 @@ type RestoreOpResult struct {
// PutBackWaiting (R-1251) marks an interrupted restore whose put-back waits for the app's drive: the message says the
// box puts the data back when the drive is there — not „start it again", which would restore the backup over it.
PutBackWaiting bool `json:"put_back_waiting,omitempty"`
// NotStarted (R-1270) marks a restore whose data is back but whose app did not start in time: not a success. A late
// start turns the record to success (markLateStart).
NotStarted bool `json:"not_started,omitempty"`
}
// RestoreResultWindow bounds how long a finished restore still counts as "what just happened".
@@ -108,3 +111,25 @@ func (m *Manager) RestoreStatus() RestoreOpStatus {
}
return st
}
// EndRestoreOpNotStarted records a restore whose data is back but whose app did not start in time (R-1270): not ok, the
// household's sentence, and the mark a late start reads.
func (m *Manager) EndRestoreOpNotStarted(message string) {
m.mu.Lock()
defer m.mu.Unlock()
m.opLast = &RestoreOpResult{Op: m.opName, Stack: m.opStack, OK: false, Message: message, FinishedAt: time.Now(), NotStarted: true}
m.opRunning = false
m.persistRestoreRecordLocked()
}
// markLateStart turns the latest record of stack to success when it is still that restore's not-started record and no
// restore runs now (R-1270). Anything else is left as it is.
func (m *Manager) markLateStart(stack, message string) {
m.mu.Lock()
defer m.mu.Unlock()
if m.opRunning || m.opLast == nil || m.opLast.Stack != stack || !m.opLast.NotStarted {
return
}
m.opLast = &RestoreOpResult{Op: m.opLast.Op, Stack: stack, OK: true, Message: message, FinishedAt: time.Now()}
m.persistRestoreRecordLocked()
}