Files
raven/internal/tracker/tracker.go
dwrz c53ee5f6ad Add intake worker
Subsystem to monitor IMAP mailbox for new messages.

Introduces:
- intake: worker that uses IDLE or polling to detect new emails.
- imap: client wrapper for connection management and IMAP commands.
- filter: logic for IMAP search and sender allow-list.
- tracker: concurrency control to prevent processing the same UID twice.
- backoff: for handling connection retries with jitter.
2026-01-04 20:59:26 +00:00

44 lines
1.0 KiB
Go

// 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)
}