6f846a0a3c
Consume configurable queues, format signals (including period), share NotifyService with HTTP, and drop duplicate bodies within 1h.
71 lines
1.4 KiB
Go
71 lines
1.4 KiB
Go
package subscriber
|
|
|
|
import (
|
|
"context"
|
|
"crypto/sha256"
|
|
"encoding/hex"
|
|
"sync"
|
|
"time"
|
|
|
|
"aiaa-notification-service/internal/cache"
|
|
)
|
|
|
|
type Deduper interface {
|
|
Claim(ctx context.Context, hash string) (bool, error)
|
|
Release(ctx context.Context, hash string) error
|
|
}
|
|
|
|
func MessageHash(body []byte) string {
|
|
sum := sha256.Sum256(body)
|
|
return hex.EncodeToString(sum[:])
|
|
}
|
|
|
|
type MemoryDeduper struct {
|
|
mu sync.Mutex
|
|
seen map[string]struct{}
|
|
}
|
|
|
|
func NewMemoryDeduper() *MemoryDeduper {
|
|
return &MemoryDeduper{seen: make(map[string]struct{})}
|
|
}
|
|
|
|
func (d *MemoryDeduper) Claim(_ context.Context, hash string) (bool, error) {
|
|
d.mu.Lock()
|
|
defer d.mu.Unlock()
|
|
if _, ok := d.seen[hash]; ok {
|
|
return false, nil
|
|
}
|
|
d.seen[hash] = struct{}{}
|
|
return true, nil
|
|
}
|
|
|
|
func (d *MemoryDeduper) Release(_ context.Context, hash string) error {
|
|
d.mu.Lock()
|
|
defer d.mu.Unlock()
|
|
delete(d.seen, hash)
|
|
return nil
|
|
}
|
|
|
|
type cacheDeduper struct {
|
|
c *cache.Cache
|
|
ttl time.Duration
|
|
}
|
|
|
|
func NewCacheDeduper(c *cache.Cache, ttl time.Duration) Deduper {
|
|
if c == nil {
|
|
return NewMemoryDeduper()
|
|
}
|
|
if ttl <= 0 {
|
|
ttl = time.Hour
|
|
}
|
|
return &cacheDeduper{c: c, ttl: ttl}
|
|
}
|
|
|
|
func (d *cacheDeduper) Claim(ctx context.Context, hash string) (bool, error) {
|
|
return d.c.ClaimDedup(ctx, hash, d.ttl)
|
|
}
|
|
|
|
func (d *cacheDeduper) Release(ctx context.Context, hash string) error {
|
|
return d.c.ReleaseDedup(ctx, hash)
|
|
}
|