Add graceful shutdown

This commit is contained in:
2026-03-03 06:00:52 +00:00
parent 119862d7ed
commit 2edb290563
5 changed files with 94 additions and 18 deletions

View File

@@ -14,6 +14,7 @@ type Store interface {
Append(id string, messages ...api.Message) (*Conversation, error)
Delete(id string) error
Size() int
Close() error
}
// MemoryStore manages conversation history in-memory with automatic expiration.
@@ -21,6 +22,7 @@ type MemoryStore struct {
conversations map[string]*Conversation
mu sync.RWMutex
ttl time.Duration
done chan struct{}
}
// Conversation holds the message history for a single conversation thread.
@@ -37,13 +39,14 @@ func NewMemoryStore(ttl time.Duration) *MemoryStore {
s := &MemoryStore{
conversations: make(map[string]*Conversation),
ttl: ttl,
done: make(chan struct{}),
}
// Start cleanup goroutine if TTL is set
if ttl > 0 {
go s.cleanup()
}
return s
}
@@ -140,16 +143,21 @@ func (s *MemoryStore) Delete(id string) error {
func (s *MemoryStore) cleanup() {
ticker := time.NewTicker(1 * time.Minute)
defer ticker.Stop()
for range ticker.C {
s.mu.Lock()
now := time.Now()
for id, conv := range s.conversations {
if now.Sub(conv.UpdatedAt) > s.ttl {
delete(s.conversations, id)
for {
select {
case <-ticker.C:
s.mu.Lock()
now := time.Now()
for id, conv := range s.conversations {
if now.Sub(conv.UpdatedAt) > s.ttl {
delete(s.conversations, id)
}
}
s.mu.Unlock()
case <-s.done:
return
}
s.mu.Unlock()
}
}
@@ -159,3 +167,9 @@ func (s *MemoryStore) Size() int {
defer s.mu.RUnlock()
return len(s.conversations)
}
// Close stops the cleanup goroutine and releases resources.
func (s *MemoryStore) Close() error {
close(s.done)
return nil
}