返回 DeepSeek-Reasonix
recovery_version.go
根目录 / desktop / internal / workspacestate / recovery_version.go
1 package workspacestate
2
3 import "context"
4
5 // restoredRecoveryVersion reports the session a source version was restored
6 // into. Entries are keyed by version, so the version, not whichever entry first
7 // reported it, decides whether recovery is still owed.
8 func restoredRecoveryVersion(state State, sourceKey, fingerprint string) (string, bool) {
9 if fingerprint == "" {
10 return "", false
11 }
12 found, sessionID := "", ""
13 for id, entry := range state.RecoveryEntries {
14 if entry.Status == "restored" && entry.SessionID != "" && entry.SourceKey == sourceKey &&
15 entry.Fingerprint == fingerprint && (found == "" || id < found) {
16 found, sessionID = id, entry.SessionID
17 }
18 }
19 return sessionID, found != ""
20 }
21
22 func settleRecoveryVersion(state *State, restored RecoveryEntry) {
23 if restored.Fingerprint == "" {
24 return
25 }
26 for id, entry := range state.RecoveryEntries {
27 if entry.Status != "restored" && entry.SourceKey == restored.SourceKey && entry.Fingerprint == restored.Fingerprint {
28 entry.Status, entry.SessionID = "restored", restored.SessionID
29 state.RecoveryEntries[id] = entry
30 }
31 }
32 }
33
34 // RebaseRecovery points a pending entry at the source version now on disk; the
35 // caller holds the source lock until its restore commits. A version already
36 // restored settles the entry to that session instead of importing it again.
37 func (s *Store) RebaseRecovery(ctx context.Context, id, fingerprint string) (RecoveryEntry, error) {
38 var rebased RecoveryEntry
39 err := s.mutate(ctx, func(state *State) error {
40 entry, ok := state.RecoveryEntries[id]
41 if !ok {
42 return ErrMutationConflict
43 }
44 if entry.Status != "restored" {
45 entry.Fingerprint = fingerprint
46 if sessionID, restored := restoredRecoveryVersion(*state, entry.SourceKey, fingerprint); restored {
47 entry.Status, entry.SessionID = "restored", sessionID
48 }
49 state.RecoveryEntries[id] = entry
50 }
51 rebased = entry
52 return nil
53 })
54 return rebased, err
55 }
56
56 lines GO