simplify options

This commit is contained in:
adlerhurst
2025-03-16 11:36:00 +01:00
parent 599a600bfb
commit ff25a516cf
4 changed files with 60 additions and 69 deletions

View File

@@ -2,7 +2,6 @@ package orchestrate
import ( import (
"context" "context"
"fmt"
"github.com/zitadel/zitadel/backend/repository" "github.com/zitadel/zitadel/backend/repository"
"github.com/zitadel/zitadel/backend/repository/cache" "github.com/zitadel/zitadel/backend/repository/cache"
@@ -15,43 +14,33 @@ import (
"github.com/zitadel/zitadel/backend/telemetry/tracing" "github.com/zitadel/zitadel/backend/telemetry/tracing"
) )
type instance struct { type InstanceOptions struct {
options
cache *cache.Instance cache *cache.Instance
} }
func Instance(opts ...InstanceConfig) *instance { type instance struct {
i := new(instance) options[InstanceOptions]
*InstanceOptions
}
func Instance(opts ...Option[InstanceOptions]) *instance {
i := instance{
options: newOptions[InstanceOptions](),
}
i.InstanceOptions = i.options.custom
for _, opt := range opts { for _, opt := range opts {
opt.applyInstance(i) opt.apply(&i.options)
} }
return i return &i
} }
func WithInstanceCache(cache *cache.Instance) instanceOption { func WithInstanceCache(cache *cache.Instance) Option[InstanceOptions] {
return func(i *instance) { return func(opts *options[InstanceOptions]) {
i.cache = cache opts.custom.cache = cache
} }
} }
type InstanceConfig interface {
applyInstance(*instance)
}
// instanceOption applies an option to the instance.
type instanceOption func(*instance)
func (io instanceOption) applyInstance(i *instance) {
io(i)
}
func (o Option) applyInstance(i *instance) {
o(&i.options)
}
func (i *instance) Create(ctx context.Context, tx database.Transaction, instance *repository.Instance) (*repository.Instance, error) { func (i *instance) Create(ctx context.Context, tx database.Transaction, instance *repository.Instance) (*repository.Instance, error) {
fmt.Println("----------------")
return traced.Wrap(i.tracer, "instance.SetUp", return traced.Wrap(i.tracer, "instance.SetUp",
handler.Chains( handler.Chains(
handler.Decorates( handler.Decorates(

View File

@@ -24,16 +24,16 @@ func Test_instance_SetUp(t *testing.T) {
} }
tests := []struct { tests := []struct {
name string name string
opts []orchestrate.InstanceConfig opts []orchestrate.Option[orchestrate.InstanceOptions]
args args args args
want *repository.Instance want *repository.Instance
wantErr bool wantErr bool
}{ }{
{ {
name: "simple", name: "simple",
opts: []orchestrate.InstanceConfig{ opts: []orchestrate.Option[orchestrate.InstanceOptions]{
orchestrate.WithTracer(tracing.NewTracer("test")), orchestrate.WithTracer[orchestrate.InstanceOptions](tracing.NewTracer("test")),
orchestrate.WithLogger(logging.New(slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelDebug})))), orchestrate.WithLogger[orchestrate.InstanceOptions](logging.New(slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelDebug})))),
orchestrate.WithInstanceCache(cache.NewInstance()), orchestrate.WithInstanceCache(cache.NewInstance()),
}, },
args: args{ args: args{
@@ -52,9 +52,9 @@ func Test_instance_SetUp(t *testing.T) {
}, },
{ {
name: "without cache", name: "without cache",
opts: []orchestrate.InstanceConfig{ opts: []orchestrate.Option[orchestrate.InstanceOptions]{
orchestrate.WithTracer(tracing.NewTracer("test")), orchestrate.WithTracer[orchestrate.InstanceOptions](tracing.NewTracer("test")),
orchestrate.WithLogger(logging.New(slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelDebug})))), orchestrate.WithLogger[orchestrate.InstanceOptions](logging.New(slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelDebug})))),
}, },
args: args{ args: args{
ctx: context.Background(), ctx: context.Background(),
@@ -72,8 +72,8 @@ func Test_instance_SetUp(t *testing.T) {
}, },
{ {
name: "without cache, tracer", name: "without cache, tracer",
opts: []orchestrate.InstanceConfig{ opts: []orchestrate.Option[orchestrate.InstanceOptions]{
orchestrate.WithLogger(logging.New(slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelDebug})))), orchestrate.WithLogger[orchestrate.InstanceOptions](logging.New(slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: slog.LevelDebug})))),
}, },
args: args{ args: args{
ctx: context.Background(), ctx: context.Background(),

View File

@@ -6,25 +6,36 @@ import (
) )
// options are the default options for orchestrators. // options are the default options for orchestrators.
type options struct { type options[T any] struct {
custom *T
tracer *tracing.Tracer tracer *tracing.Tracer
logger *logging.Logger logger *logging.Logger
} }
type Option func(*options) func newOptions[T any]() options[T] {
return options[T]{
custom: new(T),
}
}
func WithTracer(tracer *tracing.Tracer) Option { type applier interface {
return func(o *options) { apply()
}
type Option[T any] func(*options[T])
func WithTracer[T any](tracer *tracing.Tracer) Option[T] {
return func(o *options[T]) {
o.tracer = tracer o.tracer = tracer
} }
} }
func WithLogger(logger *logging.Logger) Option { func WithLogger[T any](logger *logging.Logger) Option[T] {
return func(o *options) { return func(o *options[T]) {
o.logger = logger o.logger = logger
} }
} }
func (o Option) apply(opts *options) { func (o Option[T]) apply(opts *options[T]) {
o(opts) o(opts)
} }

View File

@@ -13,41 +13,32 @@ import (
"github.com/zitadel/zitadel/backend/telemetry/tracing" "github.com/zitadel/zitadel/backend/telemetry/tracing"
) )
type user struct { type UserOptions struct {
options
cache *cache.User cache *cache.User
} }
func User(opts ...Option) *user { type user struct {
i := new(user) options[UserOptions]
*UserOptions
}
func User(opts ...Option[UserOptions]) *user {
i := user{
options: newOptions[UserOptions](),
}
i.UserOptions = i.options.custom
for _, opt := range opts { for _, opt := range opts {
opt(&i.options) opt(&i.options)
} }
return i return &i
} }
func WithUserCache(cache *cache.User) userOption { func WithUserCache(cache *cache.User) Option[UserOptions] {
return func(i *user) { return func(i *options[UserOptions]) {
i.cache = cache i.custom.cache = cache
} }
} }
type UserConfig interface {
applyUser(*user)
}
// userOption applies an option to the user.
type userOption func(*user)
func (io userOption) applyUser(i *user) {
io(i)
}
func (o Option) applyUser(i *user) {
o(&i.options)
}
func (i *user) Create(ctx context.Context, tx database.Transaction, user *repository.User) (*repository.User, error) { func (i *user) Create(ctx context.Context, tx database.Transaction, user *repository.User) (*repository.User, error) {
return traced.Wrap(i.tracer, "user.Create", return traced.Wrap(i.tracer, "user.Create",
handler.Chain( handler.Chain(
@@ -65,13 +56,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) { func (i *user) ByID(ctx context.Context, querier database.Querier, id string) (*repository.User, error) {
return handler.SkipNext( return handler.SkipNext(
i.cache.ByID, i.custom.cache.ByID,
handler.Chain( handler.Chain(
handler.Decorate( handler.Decorate(
sql.Query(querier).UserByID, sql.Query(querier).UserByID,
traced.Decorate[string, *repository.User](i.tracer, tracing.WithSpanName("user.sql.ByID")), traced.Decorate[string, *repository.User](i.tracer, tracing.WithSpanName("user.sql.ByID")),
), ),
handler.SkipNilHandler(i.cache, i.cache.Set), handler.SkipNilHandler(i.custom.cache, i.custom.cache.Set),
), ),
)(ctx, id) )(ctx, id)
} }