Skip to content

Commit

Permalink
GetBackend with functional params instead of GetBackendWithParams
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
wojas committed Nov 2, 2022
1 parent a779f8f commit e398be7
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 29 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
Expand Down
13 changes: 9 additions & 4 deletions example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
46 changes: 22 additions & 24 deletions plugins.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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")
}
Expand All @@ -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)
}

0 comments on commit e398be7

Please sign in to comment.