// Package tracker prevents duplicate processing of IMAP messages by // maintaining a transient set of active, in-flight UIDs. package tracker import ( "sync" "github.com/emersion/go-imap/v2" ) // Tracker ensures unique concurrent processing of messages. // This prevents race conditions where a message might be fetched // again before its initial processing completes. type Tracker struct { mu sync.Mutex ids map[imap.UID]struct{} } // New returns a ready-to-use Tracker. func New() *Tracker { return &Tracker{ ids: make(map[imap.UID]struct{}), } } // TryAcquire attempts to claim exclusive processing rights for a UID. // It returns true only if the UID is not currently being tracked. func (t *Tracker) TryAcquire(uid imap.UID) bool { t.mu.Lock() defer t.mu.Unlock() if _, exists := t.ids[uid]; exists { return false } t.ids[uid] = struct{}{} return true } // Release relinquishes processing rights for a UID, allowing it to be acquired again. func (t *Tracker) Release(uid imap.UID) { t.mu.Lock() defer t.mu.Unlock() delete(t.ids, uid) }