返回 DeepSeek-Reasonix
history_slice_rebuild.go
根目录 / desktop / history_slice_rebuild.go
1 package main
2
3 import (
4 "log/slog"
5 "strings"
6
7 "reasonix/internal/agent"
8 "reasonix/internal/control"
9 )
10
11 // kickHistoryIndexRebuild single-flight schedules a background display-index
12 // rebuild for a live session whose on-disk index did not validate. It never
13 // blocks the request path.
14 func (a *App) kickHistoryIndexRebuild(sessionPath string) {
15 if strings.TrimSpace(sessionPath) == "" {
16 return
17 }
18 a.historySliceMu.Lock()
19 if a.historyIndexRebuilds == nil {
20 a.historyIndexRebuilds = map[string]chan struct{}{}
21 }
22 if _, ok := a.historyIndexRebuilds[sessionPath]; ok {
23 a.historySliceMu.Unlock()
24 return
25 }
26 done := make(chan struct{})
27 a.historyIndexRebuilds[sessionPath] = done
28 a.historySliceMu.Unlock()
29 a.goSafe("historyIndexRebuild", func() {
30 defer func() {
31 a.historySliceMu.Lock()
32 close(done)
33 delete(a.historyIndexRebuilds, sessionPath)
34 a.historySliceMu.Unlock()
35 }()
36 a.rebuildHistoryIndexForLiveSession(sessionPath)
37 })
38 }
39
40 // rebuildHistoryIndexForLiveSession republishes the display index for a live
41 // session, but only when the in-memory log is exactly the persisted
42 // transcript — an append-only tail means the next save will publish a
43 // covering index anyway, and a scanned .jsonl anchor cannot describe the
44 // event-log tail.
45 func (a *App) rebuildHistoryIndexForLiveSession(sessionPath string) {
46 a.mu.RLock()
47 ctrls := make([]control.SessionAPI, 0, len(a.tabs))
48 for _, tab := range a.tabs {
49 if tab != nil && tab.Ctrl != nil {
50 ctrls = append(ctrls, tab.Ctrl)
51 }
52 }
53 a.mu.RUnlock()
54 var ctrl control.SessionAPI
55 for _, c := range ctrls {
56 if c.SessionPath() == sessionPath {
57 ctrl = c
58 break
59 }
60 }
61 wc, ok := ctrl.(historyWindowController)
62 if !ok {
63 return
64 }
65 ps, ok := wc.SessionPersistedState()
66 if !ok || !ps.UnchangedSincePersisted {
67 return
68 }
69 if err := agent.RepairSessionDisplayReadModel(sessionPath); err != nil {
70 slog.Debug("desktop: live history read-model rebuild failed", "path", sessionPath, "err", err)
71 }
72 }
73
73 lines GO