feat: add generic queue and subscription retirement

This commit is contained in:
2026-09-27 14:39:49 +08:00
parent d54bdd9847
commit c9e877c3f7
53 changed files with 1013 additions and 88 deletions

View File

@@ -24,7 +24,7 @@ func NewEventStore(db *sql.DB) *EventStore { return &EventStore{NewTaskStore(db)
var _ events.Store = (*EventStore)(nil)
const subscriptionColumns = `id,queue_id,credential_id,name,revision,enabled,filter,cursor_sequence,pending_count,max_pending,max_attempts,created_at,updated_at`
const subscriptionColumns = `id,queue_id,credential_id,name,revision,enabled,filter,cursor_sequence,pending_count,max_pending,max_attempts,created_at,updated_at,retired_at,retired_sequence`
func readSubscription(ctx context.Context, tx *sql.Tx, t auth.Token, p auth.Permissions, id core.ID, lock bool) (events.Subscription, error) {
q := `SELECT ` + subscriptionColumns + ` FROM orbit_subscriptions WHERE namespace_id=? AND id=? AND credential_id=? AND queue_id IS NOT NULL`
@@ -52,7 +52,7 @@ func readSubscription(ctx context.Context, tx *sql.Tx, t auth.Token, p auth.Perm
func scanSubscription(row scanner) (events.Subscription, error) {
var out events.Subscription
var raw []byte
err := row.Scan(&out.ID, &out.QueueID, &out.CredentialID, &out.Name, &out.Revision, &out.Enabled, &raw, &out.CursorSequence, &out.PendingCount, &out.MaxPending, &out.MaxAttempts, &out.CreatedAt, &out.UpdatedAt)
err := row.Scan(&out.ID, &out.QueueID, &out.CredentialID, &out.Name, &out.Revision, &out.Enabled, &raw, &out.CursorSequence, &out.PendingCount, &out.MaxPending, &out.MaxAttempts, &out.CreatedAt, &out.UpdatedAt, &out.RetiredAt, &out.RetiredSequence)
if err != nil {
return out, err
}
@@ -87,6 +87,9 @@ func (s *EventStore) CreateSubscription(ctx context.Context, t auth.Token, key s
} else if err != nil {
return err
}
if err := requireActiveQueue(ctx, tx, t.NamespaceID, in.QueueID); err != nil {
return err
}
head, retained, err := lockEventStream(ctx, tx, t.NamespaceID)
if err != nil {
return err
@@ -102,7 +105,7 @@ func (s *EventStore) CreateSubscription(ctx context.Context, t auth.Token, key s
return events.HistoryExpired
}
var count int
if err = tx.QueryRowContext(ctx, `SELECT COUNT(*) FROM orbit_subscriptions WHERE namespace_id=?`, t.NamespaceID).Scan(&count); err != nil {
if err = tx.QueryRowContext(ctx, `SELECT COUNT(*) FROM orbit_subscriptions WHERE namespace_id=? AND retired_at IS NULL`, t.NamespaceID).Scan(&count); err != nil {
return err
}
if count >= events.MaxSubscriptions {
@@ -158,6 +161,9 @@ func (s *EventStore) ControlSubscription(ctx context.Context, t auth.Token, id c
out.Deduplicated = true
return nil
}
if before.RetiredAt != nil {
return fault.Retired
}
if before.Revision != in.ExpectedRevision || before.Revision == math.MaxUint64 {
return fault.Conflict
}