agent: debounce session persistence
saveSession() now sets a dirty flag and starts a 2-second timer instead of immediately serializing and writing the full message history. For a 50-step turn, this reduces 50 JSON marshals + disk writes down to ~25 (one every 2s) plus a guaranteed flush at turn end and on close. flushSave() is called: - At end of turn (after setState idle) - On interrupt - On Close() - When the 2s timer fires (if still dirty)
This commit is contained in:
parent
69b90de68f
commit
bd3b46bbed
|
|
@ -289,6 +289,11 @@ type agent struct {
|
|||
submitMu sync.Mutex // serializes Submit calls (commands + turns)
|
||||
warnedContext bool // true after a context-usage warning; cleared on compaction
|
||||
auditLog *olog.Logger
|
||||
|
||||
// Debounced session persistence
|
||||
saveMu sync.Mutex
|
||||
saveDirty bool
|
||||
saveTimer *time.Timer
|
||||
}
|
||||
|
||||
// ToolCallCount returns the total number of tool calls executed in this
|
||||
|
|
@ -460,6 +465,7 @@ func NewAgentCore(cfg AgentCoreConfig) Core {
|
|||
// Close releases resources for this session, including its tmpdir.
|
||||
func (s *agent) Close() {
|
||||
s.log.Debug("Close() session=%q", s.sessionID)
|
||||
s.flushSave()
|
||||
if s.runtime != nil && s.runtime.Dispatcher != nil {
|
||||
if srv, ok := s.runtime.Dispatcher.GetServer("execute"); ok {
|
||||
if c, ok := srv.(interface{ Close() }); ok {
|
||||
|
|
@ -805,6 +811,27 @@ func (s *agent) runCompact(ctx context.Context, trigger string) (int, error) {
|
|||
}
|
||||
|
||||
func (s *agent) saveSession() {
|
||||
s.saveMu.Lock()
|
||||
s.saveDirty = true
|
||||
if s.saveTimer == nil {
|
||||
s.saveTimer = time.AfterFunc(2*time.Second, s.flushSave)
|
||||
}
|
||||
s.saveMu.Unlock()
|
||||
}
|
||||
|
||||
// flushSave immediately persists the session if dirty.
|
||||
func (s *agent) flushSave() {
|
||||
s.saveMu.Lock()
|
||||
dirty := s.saveDirty
|
||||
s.saveDirty = false
|
||||
if s.saveTimer != nil {
|
||||
s.saveTimer.Stop()
|
||||
s.saveTimer = nil
|
||||
}
|
||||
s.saveMu.Unlock()
|
||||
if !dirty {
|
||||
return
|
||||
}
|
||||
if s.session == nil || s.sessionID == "" || s.sessionsDir == "" {
|
||||
return
|
||||
}
|
||||
|
|
@ -1292,6 +1319,7 @@ func (s *agent) executeTurn(ctx context.Context, input string) string {
|
|||
s.mu.Unlock()
|
||||
replyBuf.Reset()
|
||||
s.setState("idle")
|
||||
s.flushSave()
|
||||
|
||||
if err != nil {
|
||||
// Keep completed work — only remove cancelled tool results.
|
||||
|
|
|
|||
Reference in New Issue