mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-23 14:57:46 +00:00
use current cache implementation
This commit is contained in:
56
backend/repository/cache/instance.go
vendored
56
backend/repository/cache/instance.go
vendored
@@ -1,56 +0,0 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"sync"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/repository"
|
||||
"github.com/zitadel/zitadel/backend/storage/cache"
|
||||
"github.com/zitadel/zitadel/backend/storage/cache/gomap"
|
||||
)
|
||||
|
||||
type Instance struct {
|
||||
mu *sync.RWMutex
|
||||
byID cache.Cache[string, *repository.Instance]
|
||||
byDomain cache.Cache[string, *repository.Instance]
|
||||
}
|
||||
|
||||
func NewInstance() *Instance {
|
||||
return &Instance{
|
||||
mu: &sync.RWMutex{},
|
||||
byID: gomap.New[string, *repository.Instance](),
|
||||
byDomain: gomap.New[string, *repository.Instance](),
|
||||
}
|
||||
}
|
||||
|
||||
func (i *Instance) Set(ctx context.Context, instance *repository.Instance) (*repository.Instance, error) {
|
||||
log.Println("cache.instance.set")
|
||||
i.set(instance, "")
|
||||
return instance, nil
|
||||
}
|
||||
|
||||
func (i *Instance) ByID(ctx context.Context, id string) (*repository.Instance, error) {
|
||||
i.mu.RLock()
|
||||
defer i.mu.RUnlock()
|
||||
log.Println("cache.instance.byID")
|
||||
instance, _ := i.byID.Get(id)
|
||||
return instance, nil
|
||||
}
|
||||
|
||||
func (i *Instance) ByDomain(ctx context.Context, domain string) (*repository.Instance, error) {
|
||||
i.mu.RLock()
|
||||
defer i.mu.RUnlock()
|
||||
log.Println("cache.instance.byDomain")
|
||||
instance, _ := i.byDomain.Get(domain)
|
||||
return instance, nil
|
||||
}
|
||||
|
||||
func (i *Instance) set(instance *repository.Instance, domain string) {
|
||||
i.mu.Lock()
|
||||
defer i.mu.Unlock()
|
||||
if domain != "" {
|
||||
i.byDomain.Set(domain, instance)
|
||||
}
|
||||
i.byID.Set(instance.ID, instance)
|
||||
}
|
38
backend/repository/cache/user.go
vendored
38
backend/repository/cache/user.go
vendored
@@ -1,38 +0,0 @@
|
||||
package cache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/repository"
|
||||
"github.com/zitadel/zitadel/backend/storage/cache"
|
||||
"github.com/zitadel/zitadel/backend/storage/cache/gomap"
|
||||
)
|
||||
|
||||
type User struct {
|
||||
cache.Cache[string, *repository.User]
|
||||
}
|
||||
|
||||
func NewUser() *User {
|
||||
return &User{
|
||||
Cache: gomap.New[string, *repository.User](),
|
||||
}
|
||||
}
|
||||
|
||||
// ByID implements repository.UserRepository.
|
||||
func (u *User) ByID(ctx context.Context, id string) (*repository.User, error) {
|
||||
log.Println("cache.user.byid")
|
||||
user, _ := u.Get(id)
|
||||
return user, nil
|
||||
|
||||
}
|
||||
|
||||
func (u *User) Set(ctx context.Context, user *repository.User) (*repository.User, error) {
|
||||
log.Println("cache.user.set")
|
||||
u.set(user)
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func (u *User) set(user *repository.User) {
|
||||
u.Cache.Set(user.ID, user)
|
||||
}
|
@@ -1,10 +1,37 @@
|
||||
package repository
|
||||
|
||||
import "github.com/zitadel/zitadel/backend/storage/cache"
|
||||
|
||||
type Instance struct {
|
||||
ID string
|
||||
Name string
|
||||
}
|
||||
|
||||
type InstanceIndex uint8
|
||||
|
||||
var InstanceIndices = []InstanceIndex{
|
||||
InstanceByID,
|
||||
InstanceByDomain,
|
||||
}
|
||||
|
||||
const (
|
||||
InstanceByID InstanceIndex = iota
|
||||
InstanceByDomain
|
||||
)
|
||||
|
||||
var _ cache.Entry[InstanceIndex, string] = (*Instance)(nil)
|
||||
|
||||
// Keys implements [cache.Entry].
|
||||
func (i *Instance) Keys(index InstanceIndex) (key []string) {
|
||||
switch index {
|
||||
case InstanceByID:
|
||||
return []string{i.ID}
|
||||
case InstanceByDomain:
|
||||
return []string{i.Name}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ListRequest struct {
|
||||
Limit uint16
|
||||
}
|
||||
|
@@ -2,6 +2,8 @@ package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/storage/cache"
|
||||
)
|
||||
|
||||
// Handler is a function that handles the request.
|
||||
@@ -65,7 +67,7 @@ func SkipNext[Req, Res any](handle Handler[Req, Res], next Handler[Req, Res]) Ha
|
||||
|
||||
// SkipNilHandler skips the handle function if the handler is nil.
|
||||
// The function is safe to call with nil handler.
|
||||
func SkipNilHandler[O, R any](handler *O, handle Handler[R, R]) Handler[R, R] {
|
||||
func SkipNilHandler[R any](handler any, handle Handler[R, R]) Handler[R, R] {
|
||||
return func(ctx context.Context, request R) (res R, err error) {
|
||||
if handler == nil {
|
||||
return request, nil
|
||||
@@ -73,3 +75,27 @@ func SkipNilHandler[O, R any](handler *O, handle Handler[R, R]) Handler[R, R] {
|
||||
return handle(ctx, request)
|
||||
}
|
||||
}
|
||||
|
||||
func ErrFuncToHandle[R any](fn func(context.Context, R) error) Handler[R, R] {
|
||||
return func(ctx context.Context, request R) (res R, err error) {
|
||||
err = fn(ctx, request)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
return request, nil
|
||||
}
|
||||
}
|
||||
|
||||
func NoReturnToHandle[R any](fn func(context.Context, R)) Handler[R, R] {
|
||||
return func(ctx context.Context, request R) (res R, err error) {
|
||||
fn(ctx, request)
|
||||
return request, nil
|
||||
}
|
||||
}
|
||||
|
||||
func CacheGetToHandle[I, K comparable, E cache.Entry[I, K]](fn func(context.Context, I, K) (E, bool), index I) Handler[K, E] {
|
||||
return func(ctx context.Context, request K) (res E, err error) {
|
||||
res, _ = fn(ctx, index, request)
|
||||
return res, nil
|
||||
}
|
||||
}
|
||||
|
@@ -4,18 +4,19 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/repository"
|
||||
"github.com/zitadel/zitadel/backend/repository/cache"
|
||||
"github.com/zitadel/zitadel/backend/repository/event"
|
||||
"github.com/zitadel/zitadel/backend/repository/orchestrate/handler"
|
||||
"github.com/zitadel/zitadel/backend/repository/sql"
|
||||
"github.com/zitadel/zitadel/backend/repository/telemetry/logged"
|
||||
"github.com/zitadel/zitadel/backend/repository/telemetry/traced"
|
||||
"github.com/zitadel/zitadel/backend/storage/cache"
|
||||
"github.com/zitadel/zitadel/backend/storage/cache/connector/noop"
|
||||
"github.com/zitadel/zitadel/backend/storage/database"
|
||||
"github.com/zitadel/zitadel/backend/telemetry/tracing"
|
||||
)
|
||||
|
||||
type InstanceOptions struct {
|
||||
cache *cache.Instance
|
||||
cache cache.Cache[repository.InstanceIndex, string, *repository.Instance]
|
||||
}
|
||||
|
||||
type instance struct {
|
||||
@@ -24,17 +25,17 @@ type instance struct {
|
||||
}
|
||||
|
||||
func Instance(opts ...Option[InstanceOptions]) *instance {
|
||||
i := instance{
|
||||
options: newOptions[InstanceOptions](),
|
||||
}
|
||||
i.InstanceOptions = i.options.custom
|
||||
i := new(instance)
|
||||
i.InstanceOptions = &i.options.custom
|
||||
i.cache = noop.NewCache[repository.InstanceIndex, string, *repository.Instance]()
|
||||
|
||||
for _, opt := range opts {
|
||||
opt.apply(&i.options)
|
||||
}
|
||||
return &i
|
||||
return i
|
||||
}
|
||||
|
||||
func WithInstanceCache(cache *cache.Instance) Option[InstanceOptions] {
|
||||
func WithInstanceCache(cache cache.Cache[repository.InstanceIndex, string, *repository.Instance]) Option[InstanceOptions] {
|
||||
return func(opts *options[InstanceOptions]) {
|
||||
opts.custom.cache = cache
|
||||
}
|
||||
@@ -55,7 +56,7 @@ func (i *instance) Create(ctx context.Context, tx database.Transaction, instance
|
||||
),
|
||||
handler.SkipNilHandler(i.cache,
|
||||
handler.Decorates(
|
||||
i.cache.Set,
|
||||
handler.NoReturnToHandle(i.cache.Set),
|
||||
traced.Decorate[*repository.Instance, *repository.Instance](i.tracer, tracing.WithSpanName("instance.cache.SetUp")),
|
||||
logged.Decorate[*repository.Instance, *repository.Instance](i.logger, "instance.cache.SetUp"),
|
||||
),
|
||||
@@ -66,26 +67,26 @@ func (i *instance) Create(ctx context.Context, tx database.Transaction, instance
|
||||
|
||||
func (i *instance) ByID(ctx context.Context, querier database.Querier, id string) (*repository.Instance, error) {
|
||||
return handler.SkipNext(
|
||||
i.cache.ByID,
|
||||
handler.CacheGetToHandle(i.cache.Get, repository.InstanceByID),
|
||||
handler.Chain(
|
||||
handler.Decorate(
|
||||
sql.Query(querier).InstanceByID,
|
||||
traced.Decorate[string, *repository.Instance](i.tracer, tracing.WithSpanName("instance.sql.ByID")),
|
||||
),
|
||||
handler.SkipNilHandler(i.cache, i.cache.Set),
|
||||
handler.SkipNilHandler(i.cache, handler.NoReturnToHandle(i.cache.Set)),
|
||||
),
|
||||
)(ctx, id)
|
||||
}
|
||||
|
||||
func (i *instance) ByDomain(ctx context.Context, querier database.Querier, domain string) (*repository.Instance, error) {
|
||||
return handler.SkipNext(
|
||||
i.cache.ByDomain,
|
||||
handler.CacheGetToHandle(i.cache.Get, repository.InstanceByDomain),
|
||||
handler.Chain(
|
||||
handler.Decorate(
|
||||
sql.Query(querier).InstanceByDomain,
|
||||
traced.Decorate[string, *repository.Instance](i.tracer, tracing.WithSpanName("instance.sql.ByDomain")),
|
||||
),
|
||||
handler.SkipNilHandler(i.cache, i.cache.Set),
|
||||
handler.SkipNilHandler(i.cache, handler.NoReturnToHandle(i.cache.Set)),
|
||||
),
|
||||
)(ctx, domain)
|
||||
}
|
||||
|
@@ -8,8 +8,9 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/repository"
|
||||
"github.com/zitadel/zitadel/backend/repository/cache"
|
||||
"github.com/zitadel/zitadel/backend/repository/orchestrate"
|
||||
"github.com/zitadel/zitadel/backend/storage/cache"
|
||||
"github.com/zitadel/zitadel/backend/storage/cache/connector/gomap"
|
||||
"github.com/zitadel/zitadel/backend/storage/database"
|
||||
"github.com/zitadel/zitadel/backend/storage/database/mock"
|
||||
"github.com/zitadel/zitadel/backend/telemetry/logging"
|
||||
@@ -34,7 +35,9 @@ func Test_instance_SetUp(t *testing.T) {
|
||||
opts: []orchestrate.Option[orchestrate.InstanceOptions]{
|
||||
orchestrate.WithTracer[orchestrate.InstanceOptions](tracing.NewTracer("test")),
|
||||
orchestrate.WithLogger[orchestrate.InstanceOptions](logging.New(slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelDebug})))),
|
||||
orchestrate.WithInstanceCache(cache.NewInstance()),
|
||||
orchestrate.WithInstanceCache(
|
||||
gomap.NewCache[repository.InstanceIndex, string, *repository.Instance](context.Background(), repository.InstanceIndices, cache.Config{}),
|
||||
),
|
||||
},
|
||||
args: args{
|
||||
ctx: context.Background(),
|
||||
|
@@ -7,21 +7,15 @@ import (
|
||||
|
||||
// options are the default options for orchestrators.
|
||||
type options[T any] struct {
|
||||
custom *T
|
||||
custom T
|
||||
defaultOptions
|
||||
}
|
||||
|
||||
type defaultOptions struct {
|
||||
tracer *tracing.Tracer
|
||||
logger *logging.Logger
|
||||
}
|
||||
|
||||
func newOptions[T any]() options[T] {
|
||||
return options[T]{
|
||||
custom: new(T),
|
||||
}
|
||||
}
|
||||
|
||||
type applier interface {
|
||||
apply()
|
||||
}
|
||||
|
||||
type Option[T any] func(*options[T])
|
||||
|
||||
func WithTracer[T any](tracer *tracing.Tracer) Option[T] {
|
||||
|
@@ -4,17 +4,18 @@ import (
|
||||
"context"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/repository"
|
||||
"github.com/zitadel/zitadel/backend/repository/cache"
|
||||
"github.com/zitadel/zitadel/backend/repository/event"
|
||||
"github.com/zitadel/zitadel/backend/repository/orchestrate/handler"
|
||||
"github.com/zitadel/zitadel/backend/repository/sql"
|
||||
"github.com/zitadel/zitadel/backend/repository/telemetry/traced"
|
||||
"github.com/zitadel/zitadel/backend/storage/cache"
|
||||
"github.com/zitadel/zitadel/backend/storage/cache/connector/noop"
|
||||
"github.com/zitadel/zitadel/backend/storage/database"
|
||||
"github.com/zitadel/zitadel/backend/telemetry/tracing"
|
||||
)
|
||||
|
||||
type UserOptions struct {
|
||||
cache *cache.User
|
||||
cache cache.Cache[repository.UserIndex, string, *repository.User]
|
||||
}
|
||||
|
||||
type user struct {
|
||||
@@ -23,17 +24,17 @@ type user struct {
|
||||
}
|
||||
|
||||
func User(opts ...Option[UserOptions]) *user {
|
||||
i := user{
|
||||
options: newOptions[UserOptions](),
|
||||
}
|
||||
i.UserOptions = i.options.custom
|
||||
i := new(user)
|
||||
i.UserOptions = &i.options.custom
|
||||
i.cache = noop.NewCache[repository.UserIndex, string, *repository.User]()
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(&i.options)
|
||||
}
|
||||
return &i
|
||||
return i
|
||||
}
|
||||
|
||||
func WithUserCache(cache *cache.User) Option[UserOptions] {
|
||||
func WithUserCache(cache cache.Cache[repository.UserIndex, string, *repository.User]) Option[UserOptions] {
|
||||
return func(i *options[UserOptions]) {
|
||||
i.custom.cache = cache
|
||||
}
|
||||
@@ -56,13 +57,13 @@ func (i *user) Create(ctx context.Context, tx database.Transaction, user *reposi
|
||||
|
||||
func (i *user) ByID(ctx context.Context, querier database.Querier, id string) (*repository.User, error) {
|
||||
return handler.SkipNext(
|
||||
i.custom.cache.ByID,
|
||||
handler.CacheGetToHandle(i.cache.Get, repository.UserByID),
|
||||
handler.Chain(
|
||||
handler.Decorate(
|
||||
sql.Query(querier).UserByID,
|
||||
traced.Decorate[string, *repository.User](i.tracer, tracing.WithSpanName("user.sql.ByID")),
|
||||
),
|
||||
handler.SkipNilHandler(i.custom.cache, i.custom.cache.Set),
|
||||
handler.SkipNilHandler(i.custom.cache, handler.NoReturnToHandle(i.cache.Set)),
|
||||
),
|
||||
)(ctx, id)
|
||||
}
|
||||
|
@@ -1,6 +1,33 @@
|
||||
package repository
|
||||
|
||||
import "github.com/zitadel/zitadel/backend/storage/cache"
|
||||
|
||||
type User struct {
|
||||
ID string
|
||||
Username string
|
||||
}
|
||||
|
||||
type UserIndex uint8
|
||||
|
||||
var UserIndices = []UserIndex{
|
||||
UserByID,
|
||||
UserByUsername,
|
||||
}
|
||||
|
||||
const (
|
||||
UserByID UserIndex = iota
|
||||
UserByUsername
|
||||
)
|
||||
|
||||
var _ cache.Entry[UserIndex, string] = (*User)(nil)
|
||||
|
||||
// Keys implements [cache.Entry].
|
||||
func (u *User) Keys(index UserIndex) (key []string) {
|
||||
switch index {
|
||||
case UserByID:
|
||||
return []string{u.ID}
|
||||
case UserByUsername:
|
||||
return []string{u.Username}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user