Skip to content

Commit

Permalink
Merge pull request #18 from PowerDNS/functional-options
Browse files Browse the repository at this point in the history
GetBackend with functional params instead of GetBackendWithParams
  • Loading branch information
wojas authored Nov 11, 2022
2 parents f135622 + e398be7 commit 3704775
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 3704775

Please sign in to comment.