Documentation
¶
Overview ¶
Package memory provides a thread-safe in-memory implementation of the store.PlanStore, store.SubscriptionStore, and store.UsageStore interfaces. It is intended for testing, local development, and quick-start prototyping. Do NOT use it in production — data is lost when the process restarts.
Index ¶
- type PlanStore
- func (s *PlanStore) DeletePlan(_ context.Context, id string) error
- func (s *PlanStore) GetPlan(_ context.Context, id string) (*store.Plan, error)
- func (s *PlanStore) ListPlans(_ context.Context, filter store.PlanFilter) ([]*store.Plan, error)
- func (s *PlanStore) SavePlan(_ context.Context, plan *store.Plan) error
- type ShardedSubscriptionStore
- func (s *ShardedSubscriptionStore) CreateSubscriptionIfNotActive(_ context.Context, sub *store.Subscription) error
- func (s *ShardedSubscriptionStore) DeleteSubscription(_ context.Context, id string) error
- func (s *ShardedSubscriptionStore) GetActiveSubscription(_ context.Context, subscriberID string) (*store.Subscription, error)
- func (s *ShardedSubscriptionStore) GetSubscription(_ context.Context, id string) (*store.Subscription, error)
- func (s *ShardedSubscriptionStore) GetSubscriptionByProviderID(_ context.Context, providerID string) (*store.Subscription, error)
- func (s *ShardedSubscriptionStore) ListSubscriptions(_ context.Context, filter store.SubscriptionFilter) ([]*store.Subscription, error)
- func (s *ShardedSubscriptionStore) SaveSubscription(_ context.Context, sub *store.Subscription) error
- type SubscriptionStore
- func (s *SubscriptionStore) CreateSubscriptionIfNotActive(_ context.Context, sub *store.Subscription) error
- func (s *SubscriptionStore) DeleteSubscription(_ context.Context, id string) error
- func (s *SubscriptionStore) GetActiveSubscription(_ context.Context, subscriberID string) (*store.Subscription, error)
- func (s *SubscriptionStore) GetSubscription(_ context.Context, id string) (*store.Subscription, error)
- func (s *SubscriptionStore) GetSubscriptionByProviderID(_ context.Context, providerID string) (*store.Subscription, error)
- func (s *SubscriptionStore) ListSubscriptions(_ context.Context, filter store.SubscriptionFilter) ([]*store.Subscription, error)
- func (s *SubscriptionStore) SaveSubscription(_ context.Context, sub *store.Subscription) error
- type UsageStore
- func (s *UsageStore) ListUnreportedUsage(_ context.Context, limit int) ([]*store.UsageRecord, error)
- func (s *UsageStore) ListUsageRecords(_ context.Context, subscriptionID string, from, to time.Time) ([]*store.UsageRecord, error)
- func (s *UsageStore) MarkUsageReported(_ context.Context, id string, reportedAt time.Time) error
- func (s *UsageStore) SaveUsageRecord(_ context.Context, record *store.UsageRecord) error
- func (s *UsageStore) SumUsage(_ context.Context, subscriptionID, metric string, from, to time.Time) (int64, error)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type PlanStore ¶
type PlanStore struct {
// contains filtered or unexported fields
}
PlanStore is an in-memory PlanStore.
type ShardedSubscriptionStore ¶
type ShardedSubscriptionStore struct {
// contains filtered or unexported fields
}
ShardedSubscriptionStore is the high-throughput replacement for SubscriptionStore. Use NewShardedSubscriptionStore() to create one.
func NewShardedSubscriptionStore ¶
func NewShardedSubscriptionStore() *ShardedSubscriptionStore
NewShardedSubscriptionStore returns an initialised ShardedSubscriptionStore.
func (*ShardedSubscriptionStore) CreateSubscriptionIfNotActive ¶
func (s *ShardedSubscriptionStore) CreateSubscriptionIfNotActive(_ context.Context, sub *store.Subscription) error
CreateSubscriptionIfNotActive is the atomic check+insert used by Manager.Subscribe. It holds the activeBySubscriber write lock for the entire check+insert so no concurrent goroutine can slip in between.
func (*ShardedSubscriptionStore) DeleteSubscription ¶
func (s *ShardedSubscriptionStore) DeleteSubscription(_ context.Context, id string) error
DeleteSubscription removes the subscription and evicts both global indexes.
func (*ShardedSubscriptionStore) GetActiveSubscription ¶
func (s *ShardedSubscriptionStore) GetActiveSubscription(_ context.Context, subscriberID string) (*store.Subscription, error)
GetActiveSubscription is O(1) via the global activeBySubscriber index.
func (*ShardedSubscriptionStore) GetSubscription ¶
func (s *ShardedSubscriptionStore) GetSubscription(_ context.Context, id string) (*store.Subscription, error)
func (*ShardedSubscriptionStore) GetSubscriptionByProviderID ¶
func (s *ShardedSubscriptionStore) GetSubscriptionByProviderID(_ context.Context, providerID string) (*store.Subscription, error)
GetSubscriptionByProviderID is O(1) via the global byProviderID index.
func (*ShardedSubscriptionStore) ListSubscriptions ¶
func (s *ShardedSubscriptionStore) ListSubscriptions(_ context.Context, filter store.SubscriptionFilter) ([]*store.Subscription, error)
ListSubscriptions scans all shards. Acquires each shard's read lock in turn.
func (*ShardedSubscriptionStore) SaveSubscription ¶
func (s *ShardedSubscriptionStore) SaveSubscription(_ context.Context, sub *store.Subscription) error
SaveSubscription upserts a subscription and keeps both global indexes consistent.
type SubscriptionStore ¶
type SubscriptionStore struct {
// contains filtered or unexported fields
}
SubscriptionStore is an in-memory SubscriptionStore with two secondary indexes for O(1) lookups by provider ID and active subscriber.
Index invariants (maintained by SaveSubscription and DeleteSubscription):
- byProviderID[pid] == id iff subs[id].ProviderID == pid (pid != "")
- activeBySubscriber[sid] == id iff subs[id].SubscriberID == sid AND isActiveStatus(subs[id].Status)
func NewSubscriptionStore ¶
func NewSubscriptionStore() *SubscriptionStore
NewSubscriptionStore returns an empty SubscriptionStore.
func (*SubscriptionStore) CreateSubscriptionIfNotActive ¶
func (s *SubscriptionStore) CreateSubscriptionIfNotActive(_ context.Context, sub *store.Subscription) error
CreateSubscriptionIfNotActive atomically checks whether the subscriber already has an active or trialing subscription and, if not, inserts sub. Returns *store.ErrAlreadyExists when a conflict is detected. The entire check+insert runs under a single write lock — no TOCTOU window.
func (*SubscriptionStore) DeleteSubscription ¶
func (s *SubscriptionStore) DeleteSubscription(_ context.Context, id string) error
DeleteSubscription removes the subscription and cleans up both secondary indexes.
func (*SubscriptionStore) GetActiveSubscription ¶
func (s *SubscriptionStore) GetActiveSubscription(_ context.Context, subscriberID string) (*store.Subscription, error)
GetActiveSubscription is O(1) via the activeBySubscriber index.
func (*SubscriptionStore) GetSubscription ¶
func (s *SubscriptionStore) GetSubscription(_ context.Context, id string) (*store.Subscription, error)
func (*SubscriptionStore) GetSubscriptionByProviderID ¶
func (s *SubscriptionStore) GetSubscriptionByProviderID(_ context.Context, providerID string) (*store.Subscription, error)
GetSubscriptionByProviderID is O(1) via the byProviderID index.
func (*SubscriptionStore) ListSubscriptions ¶
func (s *SubscriptionStore) ListSubscriptions(_ context.Context, filter store.SubscriptionFilter) ([]*store.Subscription, error)
func (*SubscriptionStore) SaveSubscription ¶
func (s *SubscriptionStore) SaveSubscription(_ context.Context, sub *store.Subscription) error
SaveSubscription creates or updates a subscription and keeps both secondary indexes consistent with the primary map. All three map writes happen under a single write lock so no read can observe a partially-updated state.
type UsageStore ¶
type UsageStore struct {
// contains filtered or unexported fields
}
UsageStore is an in-memory UsageStore backed by a nested index.
The index has the shape:
index[subscriptionID][metric] → []*store.UsageRecord (ordered by insertion)
This reduces SumUsage and ListUsageRecords from O(N_total) to O(k) where k is the number of records for the specific subscription+metric — typically orders of magnitude smaller than the total record count.
Production adapters MUST create a composite index on (subscription_id, metric, recorded_at) to achieve equivalent performance.
func (*UsageStore) ListUnreportedUsage ¶
func (s *UsageStore) ListUnreportedUsage(_ context.Context, limit int) ([]*store.UsageRecord, error)
ListUnreportedUsage returns up to limit records whose ProviderReportedAt is nil. Implements store.ReportableUsageStore.
func (*UsageStore) ListUsageRecords ¶
func (s *UsageStore) ListUsageRecords(_ context.Context, subscriptionID string, from, to time.Time) ([]*store.UsageRecord, error)
ListUsageRecords scans only the records belonging to subscriptionID — O(m) where m is the total records for that subscription across all metrics.
func (*UsageStore) MarkUsageReported ¶
MarkUsageReported sets ProviderReportedAt on the record with the given ID. Implements store.ReportableUsageStore.
func (*UsageStore) SaveUsageRecord ¶
func (s *UsageStore) SaveUsageRecord(_ context.Context, record *store.UsageRecord) error