From e398be7a355bd3b162fb66ebf52d0a6ea77f7e31 Mon Sep 17 00:00:00 2001 From: Konrad Wojas Date: Wed, 2 Nov 2022 15:58:16 +0800 Subject: [PATCH] GetBackend with functional params instead of GetBackendWithParams Instead of deprecating GetBackend in favor of a new GetBackendWithParams, extend the GetBackend signature with variadic functional params. This way existing code can simply keep calling the same function, and we have even more flexibility in the options we provide in the future. --- README.md | 2 +- example_test.go | 13 +++++++++---- plugins.go | 46 ++++++++++++++++++++++------------------------ 3 files changed, 32 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index c0c76cb..a502ade 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ type Interface interface { To instantiate a backend, `_`-import all the backends that you want to register, and call: ```go -func GetBackendWithParams(ctx context.Context, typeName string, params InitParams) (Interface, error) +func GetBackend(ctx context.Context, typeName string, options map[string]any, params ...Param) (Interface, error) ``` An example can be found in `example_test.go`. diff --git a/example_test.go b/example_test.go index 889fe3e..6d5cfc0 100644 --- a/example_test.go +++ b/example_test.go @@ -15,10 +15,15 @@ func Example() { // Do not forget the: // import _ "github.com/PowerDNS/simpleblob/backends/memory" ctx := context.Background() - storage, err := simpleblob.GetBackendWithParams(ctx, "memory", simpleblob.InitParams{ - OptionMap: map[string]interface{}{}, // add key-value options here - Logger: logr.Discard(), // replace with a real logger - }) + storage, err := simpleblob.GetBackend( + ctx, + "memory", + map[string]interface{}{ + // add key-value options here + "foo": "example", + }, + simpleblob.WithLogger(logr.Discard()), // replace with a real logger + ) check(err) err = storage.Store(ctx, "example.txt", []byte("hello")) check(err) diff --git a/plugins.go b/plugins.go index 41dd354..1dc8698 100644 --- a/plugins.go +++ b/plugins.go @@ -55,6 +55,18 @@ func (ip InitParams) OptionsThroughYAML(dest interface{}) error { return nil } +// Param is the type of extra init parameters. It is returned by +// calling functional params like WithLogger. +type Param func(ip *InitParams) + +// WithLogger is a GetBackend parameter that sets the logr.Logger to use in the +// backends. +func WithLogger(log logr.Logger) Param { + return func(ip *InitParams) { + ip.Logger = log + } +} + // backends is the internal backend registry var ( mu sync.Mutex @@ -70,33 +82,15 @@ func RegisterBackend(typeName string, initFunc InitFunc) { // GetBackend creates a new backend instance of given typeName. This type must // have been previously registered with RegisterBackend. -// The options map contains backend dependant key-value options. Some backends -// take no options, others require some specific options. -// The lifetime of the context passed in must span the lifetime of the whole -// backend instance, not just the init time, so do not set any timeout on it! -// -// Deprecated: consider switching to GetBackendWithParams -func GetBackend(ctx context.Context, typeName string, options map[string]interface{}) (Interface, error) { - p := InitParams{OptionMap: options} - return GetBackendWithParams(ctx, typeName, p) -} - -// GetBackendWithParams creates a new backend instance of given typeName. This type must -// have been previously registered with RegisterBackend. -// Unlike the old GetBackend, this directly accepts an InitParams struct which allows -// us to add more options on the future. -// -// One notable addition is the InitParams.Logger field that passes a logr.Logger -// to the backend. // // The options map contains backend dependant key-value options. Some backends // take no options, others require some specific options. // +// Additional parameters can be passed with extra arguments, like WithLogger. +// // The lifetime of the context passed in must span the lifetime of the whole // backend instance, not just the init time, so do not set any timeout on it! -// TODO: the context lifetime requirement is perhaps error prone and this does -// not allow setting an init timeout. Not sure what would be a good solution. -func GetBackendWithParams(ctx context.Context, typeName string, params InitParams) (Interface, error) { +func GetBackend(ctx context.Context, typeName string, options OptionMap, params ...Param) (Interface, error) { if typeName == "" { return nil, fmt.Errorf("no storage.type configured") } @@ -106,8 +100,12 @@ func GetBackendWithParams(ctx context.Context, typeName string, params InitParam if !exists { return nil, fmt.Errorf("storage.type %q not found or registered", typeName) } - if params.Logger.GetSink() == nil { - params.Logger = logr.Discard() + p := InitParams{OptionMap: options} + for _, param := range params { + param(&p) + } + if p.Logger.GetSink() == nil { + p.Logger = logr.Discard() } - return initFunc(ctx, params) + return initFunc(ctx, p) }