87 lines
3.7 KiB
Go
87 lines
3.7 KiB
Go
// Package routepublisher composes one PostgreSQL-backed route-state store
|
|
// (notificationstore) with one Redis-backed lease store (redisstate.LeaseStore)
|
|
// behind the publisher worker contracts. The composition lets push and email
|
|
// publishers keep their existing one-store dependency while Stage 5 of
|
|
// `PG_PLAN.md` splits durable state to PostgreSQL and the short-lived
|
|
// per-replica exclusivity lease to Redis.
|
|
package routepublisher
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"time"
|
|
|
|
"galaxy/notification/internal/adapters/postgres/notificationstore"
|
|
"galaxy/notification/internal/adapters/redisstate"
|
|
"galaxy/notification/internal/service/acceptintent"
|
|
"galaxy/notification/internal/service/routestate"
|
|
"galaxy/notification/internal/telemetry"
|
|
)
|
|
|
|
// Store delegates each route-publisher method to either the durable state
|
|
// store (PostgreSQL) or the lease store (Redis), preserving the umbrella
|
|
// contract consumed by `worker.PushPublisher` and `worker.EmailPublisher`.
|
|
type Store struct {
|
|
state *notificationstore.Store
|
|
leases *redisstate.LeaseStore
|
|
}
|
|
|
|
// New constructs one composite route-publisher store. Both dependencies are
|
|
// required: the SQL store owns route lifecycle and dead-letter persistence,
|
|
// and the lease store owns the short-lived per-replica exclusivity hint
|
|
// retained on Redis per PG_PLAN.md §5.
|
|
func New(state *notificationstore.Store, leases *redisstate.LeaseStore) (*Store, error) {
|
|
if state == nil {
|
|
return nil, errors.New("new route publisher store: nil notification state store")
|
|
}
|
|
if leases == nil {
|
|
return nil, errors.New("new route publisher store: nil lease store")
|
|
}
|
|
return &Store{state: state, leases: leases}, nil
|
|
}
|
|
|
|
// ListDueRoutes delegates to the SQL store.
|
|
func (store *Store) ListDueRoutes(ctx context.Context, now time.Time, limit int64) ([]routestate.ScheduledRoute, error) {
|
|
return store.state.ListDueRoutes(ctx, now, limit)
|
|
}
|
|
|
|
// TryAcquireRouteLease delegates to the Redis lease store.
|
|
func (store *Store) TryAcquireRouteLease(ctx context.Context, notificationID string, routeID string, token string, ttl time.Duration) (bool, error) {
|
|
return store.leases.TryAcquireRouteLease(ctx, notificationID, routeID, token, ttl)
|
|
}
|
|
|
|
// ReleaseRouteLease delegates to the Redis lease store.
|
|
func (store *Store) ReleaseRouteLease(ctx context.Context, notificationID string, routeID string, token string) error {
|
|
return store.leases.ReleaseRouteLease(ctx, notificationID, routeID, token)
|
|
}
|
|
|
|
// GetNotification delegates to the SQL store.
|
|
func (store *Store) GetNotification(ctx context.Context, notificationID string) (acceptintent.NotificationRecord, bool, error) {
|
|
return store.state.GetNotification(ctx, notificationID)
|
|
}
|
|
|
|
// GetRoute delegates to the SQL store.
|
|
func (store *Store) GetRoute(ctx context.Context, notificationID string, routeID string) (acceptintent.NotificationRoute, bool, error) {
|
|
return store.state.GetRoute(ctx, notificationID, routeID)
|
|
}
|
|
|
|
// CompleteRoutePublished delegates to the SQL store.
|
|
func (store *Store) CompleteRoutePublished(ctx context.Context, input routestate.CompleteRoutePublishedInput) error {
|
|
return store.state.CompleteRoutePublished(ctx, input)
|
|
}
|
|
|
|
// CompleteRouteFailed delegates to the SQL store.
|
|
func (store *Store) CompleteRouteFailed(ctx context.Context, input routestate.CompleteRouteFailedInput) error {
|
|
return store.state.CompleteRouteFailed(ctx, input)
|
|
}
|
|
|
|
// CompleteRouteDeadLetter delegates to the SQL store.
|
|
func (store *Store) CompleteRouteDeadLetter(ctx context.Context, input routestate.CompleteRouteDeadLetterInput) error {
|
|
return store.state.CompleteRouteDeadLetter(ctx, input)
|
|
}
|
|
|
|
// ReadRouteScheduleSnapshot delegates to the SQL store.
|
|
func (store *Store) ReadRouteScheduleSnapshot(ctx context.Context) (telemetry.RouteScheduleSnapshot, error) {
|
|
return store.state.ReadRouteScheduleSnapshot(ctx)
|
|
}
|