Services are in a map now

This commit is contained in:
Daniel Ponte 2025-02-14 13:29:47 -05:00
parent 1e2e606130
commit ce5505de0b
9 changed files with 92 additions and 14 deletions

View file

@ -12,6 +12,7 @@ import (
"dynatron.me/x/stillbox/pkg/database"
"dynatron.me/x/stillbox/pkg/rbac"
"dynatron.me/x/stillbox/pkg/rbac/entities"
"dynatron.me/x/stillbox/pkg/services"
"dynatron.me/x/stillbox/pkg/talkgroups/tgstore"
"dynatron.me/x/stillbox/pkg/users"
@ -55,11 +56,11 @@ type storeCtxKey string
const StoreCtxKey storeCtxKey = "store"
func CtxWithStore(ctx context.Context, s Store) context.Context {
return context.WithValue(ctx, StoreCtxKey, s)
return services.WithValue(ctx, StoreCtxKey, s)
}
func FromCtx(ctx context.Context) Store {
s, ok := ctx.Value(StoreCtxKey).(Store)
s, ok := services.Value(ctx, StoreCtxKey).(Store)
if !ok {
panic("no call store in context")
}

View file

@ -7,6 +7,7 @@ import (
"strings"
"dynatron.me/x/stillbox/pkg/config"
"dynatron.me/x/stillbox/pkg/services"
sqlembed "dynatron.me/x/stillbox/sql"
"github.com/golang-migrate/migrate/v4"
_ "github.com/golang-migrate/migrate/v4/database/pgx/v5"
@ -144,7 +145,8 @@ const DBCtxKey dBCtxKey = "dbctx"
// FromCtx returns the database handle from the provided Context.
func FromCtx(ctx context.Context) Store {
c, ok := ctx.Value(DBCtxKey).(Store)
sv := services.Value(ctx, DBCtxKey)
c, ok := sv.(Store)
if !ok {
panic("no DB in context")
}
@ -154,7 +156,7 @@ func FromCtx(ctx context.Context) Store {
// CtxWithDB returns a Context with the provided database handle.
func CtxWithDB(ctx context.Context, conn Store) context.Context {
return context.WithValue(ctx, DBCtxKey, conn)
return services.WithValue(ctx, DBCtxKey, conn)
}
// IsNoRows is a convenience function that returns whether a returned error is a database

View file

@ -11,6 +11,7 @@ import (
"dynatron.me/x/stillbox/pkg/incidents"
"dynatron.me/x/stillbox/pkg/rbac"
"dynatron.me/x/stillbox/pkg/rbac/entities"
"dynatron.me/x/stillbox/pkg/services"
"dynatron.me/x/stillbox/pkg/talkgroups"
"dynatron.me/x/stillbox/pkg/users"
"github.com/google/uuid"
@ -67,11 +68,11 @@ type storeCtxKey string
const StoreCtxKey storeCtxKey = "store"
func CtxWithStore(ctx context.Context, s Store) context.Context {
return context.WithValue(ctx, StoreCtxKey, s)
return services.WithValue(ctx, StoreCtxKey, s)
}
func FromCtx(ctx context.Context) Store {
s, ok := ctx.Value(StoreCtxKey).(Store)
s, ok := services.Value(ctx, StoreCtxKey).(Store)
if !ok {
return NewStore()
}

View file

@ -5,6 +5,7 @@ import (
"errors"
"dynatron.me/x/stillbox/pkg/rbac/entities"
"dynatron.me/x/stillbox/pkg/services"
"github.com/el-mike/restrict/v2"
"github.com/el-mike/restrict/v2/adapters"
@ -33,7 +34,7 @@ type rbacCtxKey string
const RBACCtxKey rbacCtxKey = "rbac"
func FromCtx(ctx context.Context) RBAC {
rbac, ok := ctx.Value(RBACCtxKey).(RBAC)
rbac, ok := services.Value(ctx, RBACCtxKey).(RBAC)
if !ok {
panic("no RBAC in context")
}
@ -42,7 +43,7 @@ func FromCtx(ctx context.Context) RBAC {
}
func CtxWithRBAC(ctx context.Context, rbac RBAC) context.Context {
return context.WithValue(ctx, RBACCtxKey, rbac)
return services.WithValue(ctx, RBACCtxKey, rbac)
}
var (

View file

@ -19,6 +19,7 @@ import (
"dynatron.me/x/stillbox/pkg/rbac"
"dynatron.me/x/stillbox/pkg/rbac/policy"
"dynatron.me/x/stillbox/pkg/rest"
"dynatron.me/x/stillbox/pkg/services"
"dynatron.me/x/stillbox/pkg/shares"
"dynatron.me/x/stillbox/pkg/sinks"
"dynatron.me/x/stillbox/pkg/sources"
@ -158,6 +159,9 @@ func New(ctx context.Context, cfg *config.Configuration) (*Server, error) {
}
func (s *Server) fillCtx(ctx context.Context) context.Context {
svc := services.New()
ctx = services.CtxWith(ctx, svc)
ctx = database.CtxWithDB(ctx, s.db)
ctx = tgstore.CtxWithStore(ctx, s.tgs)
ctx = users.CtxWithStore(ctx, s.users)

66
pkg/services/services.go Normal file
View file

@ -0,0 +1,66 @@
// Package services avoids having to wrap contexts so much for multiple services.
package services
import (
"context"
"sync"
)
type Services interface {
Set(key, val any)
Value(key any) any
}
type services struct {
sync.RWMutex
m map[any]any
}
func New() Services {
return &services{
m: make(map[any]any),
}
}
func CtxWith(ctx context.Context, svc Services) context.Context {
return context.WithValue(ctx, ServiceKey, svc)
}
func (s *services) Value(key any) any {
s.RLock()
defer s.RUnlock()
return s.m[key]
}
func (s *services) Set(key, val any) {
s.Lock()
defer s.Unlock()
s.m[key] = val
}
type serviceKey string
const ServiceKey serviceKey = "service"
func WithValue(ctx context.Context, key, val any) context.Context {
v := ctx.Value(ServiceKey)
if v == nil {
return context.WithValue(ctx, key, val)
}
sv := v.(Services)
sv.Set(key, val)
return ctx
}
func Value(ctx context.Context, key any) any {
sv := ctx.Value(ServiceKey)
if sv == nil {
return ctx.Value(key)
}
return sv.(Services).Value(key)
}

View file

@ -10,6 +10,7 @@ import (
"dynatron.me/x/stillbox/pkg/database"
"dynatron.me/x/stillbox/pkg/rbac"
"dynatron.me/x/stillbox/pkg/rbac/entities"
"dynatron.me/x/stillbox/pkg/services"
"dynatron.me/x/stillbox/pkg/users"
"github.com/jackc/pgx/v5"
)
@ -169,11 +170,11 @@ type storeCtxKey string
const StoreCtxKey storeCtxKey = "store"
func CtxWithStore(ctx context.Context, s Shares) context.Context {
return context.WithValue(ctx, StoreCtxKey, s)
return services.WithValue(ctx, StoreCtxKey, s)
}
func FromCtx(ctx context.Context) Shares {
s, ok := ctx.Value(StoreCtxKey).(Shares)
s, ok := services.Value(ctx, StoreCtxKey).(Shares)
if !ok {
panic("no shares store in context")
}

View file

@ -13,6 +13,7 @@ import (
"dynatron.me/x/stillbox/pkg/database"
"dynatron.me/x/stillbox/pkg/rbac"
"dynatron.me/x/stillbox/pkg/rbac/entities"
"dynatron.me/x/stillbox/pkg/services"
tgsp "dynatron.me/x/stillbox/pkg/talkgroups"
"dynatron.me/x/stillbox/pkg/users"
@ -172,11 +173,11 @@ type storeCtxKey string
const StoreCtxKey storeCtxKey = "store"
func CtxWithStore(ctx context.Context, s Store) context.Context {
return context.WithValue(ctx, StoreCtxKey, s)
return services.WithValue(ctx, StoreCtxKey, s)
}
func FromCtx(ctx context.Context) Store {
s, ok := ctx.Value(StoreCtxKey).(Store)
s, ok := services.Value(ctx, StoreCtxKey).(Store)
if !ok {
panic("no tg store in context")
}

View file

@ -6,6 +6,7 @@ import (
"dynatron.me/x/stillbox/internal/cache"
"dynatron.me/x/stillbox/pkg/database"
"dynatron.me/x/stillbox/pkg/services"
)
var (
@ -49,11 +50,11 @@ type storeCtxKey string
const StoreCtxKey storeCtxKey = "store"
func CtxWithStore(ctx context.Context, s Store) context.Context {
return context.WithValue(ctx, StoreCtxKey, s)
return services.WithValue(ctx, StoreCtxKey, s)
}
func FromCtx(ctx context.Context) Store {
s, ok := ctx.Value(StoreCtxKey).(Store)
s, ok := services.Value(ctx, StoreCtxKey).(Store)
if !ok {
panic("no users store in context")
}