Each kept its own hour of quiet per event, so a budget spent on a team both control planes served was announced by each. An event is now claimed in the store before it is sent (notify_sent, migration 0043; one statement, so two asking at once cannot both win), and only the claimer sends it. A store that cannot be asked sends it anyway. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
24 lines
746 B
Go
24 lines
746 B
Go
package store
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
)
|
|
|
|
// ClaimNotice claims the sending of a notification: true when nobody has
|
|
// sent the same one within the window, and from now on, nobody else may
|
|
// until it has passed. One statement, so two control planes asking at once
|
|
// cannot both be told yes.
|
|
func (s *DB) ClaimNotice(ctx context.Context, key string, at time.Time, window time.Duration) (bool, error) {
|
|
now := at.UnixMilli()
|
|
res, err := s.db.ExecContext(ctx,
|
|
`INSERT INTO notify_sent (key, sent_at) VALUES (?, ?)
|
|
ON CONFLICT (key) DO UPDATE SET sent_at = excluded.sent_at WHERE notify_sent.sent_at < ?`,
|
|
key, now, now-window.Milliseconds())
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
n, err := res.RowsAffected()
|
|
return n == 1, err
|
|
}
|