ituoke/internal/agent/conversation_locks.go

39 lines
817 B
Go

package agent
import "context"
type conversationLock struct {
gate chan struct{}
users int
}
// Serialize turns within each conversation while allowing different chats to stream.
func (s *Service) lockConversation(ctx context.Context, id string) (func(), error) {
s.chatMu.Lock()
if s.chatLocks == nil {
s.chatLocks = make(map[string]*conversationLock)
}
lock := s.chatLocks[id]
if lock == nil {
lock = &conversationLock{gate: make(chan struct{}, 1)}
s.chatLocks[id] = lock
}
lock.users++
s.chatMu.Unlock()
releaseRef := func() {
s.chatMu.Lock()
lock.users--
if lock.users == 0 {
delete(s.chatLocks, id)
}
s.chatMu.Unlock()
}
select {
case lock.gate <- struct{}{}:
return func() { <-lock.gate; releaseRef() }, nil
case <-ctx.Done():
releaseRef()
return nil, ctx.Err()
}
}