Skip to content

Commit

Permalink
feat!: introduced context.Context to client and provider api (#75)
Browse files Browse the repository at this point in the history
* feat!: introduced context.Context to client and provider api

Signed-off-by: Skye Gill <[email protected]>
  • Loading branch information
skyerus authored Sep 23, 2022
1 parent e843f5d commit d850c88
Show file tree
Hide file tree
Showing 10 changed files with 258 additions and 172 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,16 @@ While you'll likely want a provider for your specific backend, we've provided a
package main

import (
"context"
"github.com/open-feature/go-sdk/pkg/openfeature"
)

func main() {
openfeature.SetProvider(openfeature.NoopProvider{})
client := openfeature.NewClient("app")
value, err := client.BooleanValue("v2_enabled", false, openfeature.EvaluationContext{}, openfeature.EvaluationOptions{})
value, err := client.BooleanValue(
context.Background(), "v2_enabled", false, openfeature.EvaluationContext{}, openfeature.EvaluationOptions{},
)
}
```

Expand Down
164 changes: 117 additions & 47 deletions pkg/openfeature/client.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package openfeature

import (
"context"
"errors"
"fmt"

Expand All @@ -13,16 +14,16 @@ type IClient interface {
AddHooks(hooks ...Hook)
SetEvaluationContext(evalCtx EvaluationContext)
EvaluationContext() EvaluationContext
BooleanValue(flag string, defaultValue bool, evalCtx EvaluationContext, options EvaluationOptions) (bool, error)
StringValue(flag string, defaultValue string, evalCtx EvaluationContext, options EvaluationOptions) (string, error)
FloatValue(flag string, defaultValue float64, evalCtx EvaluationContext, options EvaluationOptions) (float64, error)
IntValue(flag string, defaultValue int64, evalCtx EvaluationContext, options EvaluationOptions) (int64, error)
ObjectValue(flag string, defaultValue interface{}, evalCtx EvaluationContext, options EvaluationOptions) (interface{}, error)
BooleanValueDetails(flag string, defaultValue bool, evalCtx EvaluationContext, options EvaluationOptions) (EvaluationDetails, error)
StringValueDetails(flag string, defaultValue string, evalCtx EvaluationContext, options EvaluationOptions) (EvaluationDetails, error)
FloatValueDetails(flag string, defaultValue float64, evalCtx EvaluationContext, options EvaluationOptions) (EvaluationDetails, error)
IntValueDetails(flag string, defaultValue int64, evalCtx EvaluationContext, options EvaluationOptions) (EvaluationDetails, error)
ObjectValueDetails(flag string, defaultValue interface{}, evalCtx EvaluationContext, options EvaluationOptions) (EvaluationDetails, error)
BooleanValue(ctx context.Context, flag string, defaultValue bool, evalCtx EvaluationContext, options EvaluationOptions) (bool, error)
StringValue(ctx context.Context, flag string, defaultValue string, evalCtx EvaluationContext, options EvaluationOptions) (string, error)
FloatValue(ctx context.Context, flag string, defaultValue float64, evalCtx EvaluationContext, options EvaluationOptions) (float64, error)
IntValue(ctx context.Context, flag string, defaultValue int64, evalCtx EvaluationContext, options EvaluationOptions) (int64, error)
ObjectValue(ctx context.Context, flag string, defaultValue interface{}, evalCtx EvaluationContext, options EvaluationOptions) (interface{}, error)
BooleanValueDetails(ctx context.Context, flag string, defaultValue bool, evalCtx EvaluationContext, options EvaluationOptions) (EvaluationDetails, error)
StringValueDetails(ctx context.Context, flag string, defaultValue string, evalCtx EvaluationContext, options EvaluationOptions) (EvaluationDetails, error)
FloatValueDetails(ctx context.Context, flag string, defaultValue float64, evalCtx EvaluationContext, options EvaluationOptions) (EvaluationDetails, error)
IntValueDetails(ctx context.Context, flag string, defaultValue int64, evalCtx EvaluationContext, options EvaluationOptions) (EvaluationDetails, error)
ObjectValueDetails(ctx context.Context, flag string, defaultValue interface{}, evalCtx EvaluationContext, options EvaluationOptions) (EvaluationDetails, error)
}

// ClientMetadata provides a client's metadata
Expand Down Expand Up @@ -112,10 +113,16 @@ type EvaluationDetails struct {
InterfaceResolutionDetail
}

// BooleanValue return boolean evaluation for flag
func (c Client) BooleanValue(flag string, defaultValue bool, evalCtx EvaluationContext, options EvaluationOptions) (bool, error) {

evalDetails, err := c.evaluate(flag, Boolean, defaultValue, evalCtx, options)
// BooleanValue performs a flag evaluation that returns a boolean.
//
// Parameters:
// - ctx is the standard go context struct used to manage requests (e.g. timeouts)
// - flag is the key that uniquely identifies a particular flag
// - defaultValue is returned if an error occurs
// - evalCtx is the evaluation context used in a flag evaluation (not to be confused with ctx)
// - options are optional additional evaluation options
func (c Client) BooleanValue(ctx context.Context, flag string, defaultValue bool, evalCtx EvaluationContext, options EvaluationOptions) (bool, error) {
evalDetails, err := c.evaluate(ctx, flag, Boolean, defaultValue, evalCtx, options)
if err != nil {
return defaultValue, err
}
Expand All @@ -133,9 +140,16 @@ func (c Client) BooleanValue(flag string, defaultValue bool, evalCtx EvaluationC
return value, nil
}

// StringValue return string evaluation for flag
func (c Client) StringValue(flag string, defaultValue string, evalCtx EvaluationContext, options EvaluationOptions) (string, error) {
evalDetails, err := c.evaluate(flag, String, defaultValue, evalCtx, options)
// StringValue performs a flag evaluation that returns a string.
//
// Parameters:
// - ctx is the standard go context struct used to manage requests (e.g. timeouts)
// - flag is the key that uniquely identifies a particular flag
// - defaultValue is returned if an error occurs
// - evalCtx is the evaluation context used in a flag evaluation (not to be confused with ctx)
// - options are optional additional evaluation options
func (c Client) StringValue(ctx context.Context, flag string, defaultValue string, evalCtx EvaluationContext, options EvaluationOptions) (string, error) {
evalDetails, err := c.evaluate(ctx, flag, String, defaultValue, evalCtx, options)
if err != nil {
return defaultValue, err
}
Expand All @@ -153,9 +167,16 @@ func (c Client) StringValue(flag string, defaultValue string, evalCtx Evaluation
return value, nil
}

// FloatValue return float evaluation for flag
func (c Client) FloatValue(flag string, defaultValue float64, evalCtx EvaluationContext, options EvaluationOptions) (float64, error) {
evalDetails, err := c.evaluate(flag, Float, defaultValue, evalCtx, options)
// FloatValue performs a flag evaluation that returns a float64.
//
// Parameters:
// - ctx is the standard go context struct used to manage requests (e.g. timeouts)
// - flag is the key that uniquely identifies a particular flag
// - defaultValue is returned if an error occurs
// - evalCtx is the evaluation context used in a flag evaluation (not to be confused with ctx)
// - options are optional additional evaluation options
func (c Client) FloatValue(ctx context.Context, flag string, defaultValue float64, evalCtx EvaluationContext, options EvaluationOptions) (float64, error) {
evalDetails, err := c.evaluate(ctx, flag, Float, defaultValue, evalCtx, options)
if err != nil {
return defaultValue, err
}
Expand All @@ -173,9 +194,16 @@ func (c Client) FloatValue(flag string, defaultValue float64, evalCtx Evaluation
return value, nil
}

// IntValue return int evaluation for flag
func (c Client) IntValue(flag string, defaultValue int64, evalCtx EvaluationContext, options EvaluationOptions) (int64, error) {
evalDetails, err := c.evaluate(flag, Int, defaultValue, evalCtx, options)
// IntValue performs a flag evaluation that returns an int64.
//
// Parameters:
// - ctx is the standard go context struct used to manage requests (e.g. timeouts)
// - flag is the key that uniquely identifies a particular flag
// - defaultValue is returned if an error occurs
// - evalCtx is the evaluation context used in a flag evaluation (not to be confused with ctx)
// - options are optional additional evaluation options
func (c Client) IntValue(ctx context.Context, flag string, defaultValue int64, evalCtx EvaluationContext, options EvaluationOptions) (int64, error) {
evalDetails, err := c.evaluate(ctx, flag, Int, defaultValue, evalCtx, options)
if err != nil {
return defaultValue, err
}
Expand All @@ -193,39 +221,81 @@ func (c Client) IntValue(flag string, defaultValue int64, evalCtx EvaluationCont
return value, nil
}

// ObjectValue return object evaluation for flag
func (c Client) ObjectValue(flag string, defaultValue interface{}, evalCtx EvaluationContext, options EvaluationOptions) (interface{}, error) {
evalDetails, err := c.evaluate(flag, Object, defaultValue, evalCtx, options)
// ObjectValue performs a flag evaluation that returns an object.
//
// Parameters:
// - ctx is the standard go context struct used to manage requests (e.g. timeouts)
// - flag is the key that uniquely identifies a particular flag
// - defaultValue is returned if an error occurs
// - evalCtx is the evaluation context used in a flag evaluation (not to be confused with ctx)
// - options are optional additional evaluation options
func (c Client) ObjectValue(ctx context.Context, flag string, defaultValue interface{}, evalCtx EvaluationContext, options EvaluationOptions) (interface{}, error) {
evalDetails, err := c.evaluate(ctx, flag, Object, defaultValue, evalCtx, options)
return evalDetails.Value, err
}

// BooleanValueDetails return boolean evaluation for flag
func (c Client) BooleanValueDetails(flag string, defaultValue bool, evalCtx EvaluationContext, options EvaluationOptions) (EvaluationDetails, error) {
return c.evaluate(flag, Boolean, defaultValue, evalCtx, options)
// BooleanValueDetails performs a flag evaluation that returns an evaluation details struct.
//
// Parameters:
// - ctx is the standard go context struct used to manage requests (e.g. timeouts)
// - flag is the key that uniquely identifies a particular flag
// - defaultValue is returned if an error occurs
// - evalCtx is the evaluation context used in a flag evaluation (not to be confused with ctx)
// - options are optional additional evaluation options
func (c Client) BooleanValueDetails(ctx context.Context, flag string, defaultValue bool, evalCtx EvaluationContext, options EvaluationOptions) (EvaluationDetails, error) {
return c.evaluate(ctx, flag, Boolean, defaultValue, evalCtx, options)
}

// StringValueDetails return string evaluation for flag
func (c Client) StringValueDetails(flag string, defaultValue string, evalCtx EvaluationContext, options EvaluationOptions) (EvaluationDetails, error) {
return c.evaluate(flag, String, defaultValue, evalCtx, options)
// StringValueDetails performs a flag evaluation that returns an evaluation details struct.
//
// Parameters:
// - ctx is the standard go context struct used to manage requests (e.g. timeouts)
// - flag is the key that uniquely identifies a particular flag
// - defaultValue is returned if an error occurs
// - evalCtx is the evaluation context used in a flag evaluation (not to be confused with ctx)
// - options are optional additional evaluation options
func (c Client) StringValueDetails(ctx context.Context, flag string, defaultValue string, evalCtx EvaluationContext, options EvaluationOptions) (EvaluationDetails, error) {
return c.evaluate(ctx, flag, String, defaultValue, evalCtx, options)
}

// FloatValueDetails return float evaluation for flag
func (c Client) FloatValueDetails(flag string, defaultValue float64, evalCtx EvaluationContext, options EvaluationOptions) (EvaluationDetails, error) {
return c.evaluate(flag, Float, defaultValue, evalCtx, options)
// FloatValueDetails performs a flag evaluation that returns an evaluation details struct.
//
// Parameters:
// - ctx is the standard go context struct used to manage requests (e.g. timeouts)
// - flag is the key that uniquely identifies a particular flag
// - defaultValue is returned if an error occurs
// - evalCtx is the evaluation context used in a flag evaluation (not to be confused with ctx)
// - options are optional additional evaluation options
func (c Client) FloatValueDetails(ctx context.Context, flag string, defaultValue float64, evalCtx EvaluationContext, options EvaluationOptions) (EvaluationDetails, error) {
return c.evaluate(ctx, flag, Float, defaultValue, evalCtx, options)
}

// IntValueDetails return int evaluation for flag
func (c Client) IntValueDetails(flag string, defaultValue int64, evalCtx EvaluationContext, options EvaluationOptions) (EvaluationDetails, error) {
return c.evaluate(flag, Int, defaultValue, evalCtx, options)
// IntValueDetails performs a flag evaluation that returns an evaluation details struct.
//
// Parameters:
// - ctx is the standard go context struct used to manage requests (e.g. timeouts)
// - flag is the key that uniquely identifies a particular flag
// - defaultValue is returned if an error occurs
// - evalCtx is the evaluation context used in a flag evaluation (not to be confused with ctx)
// - options are optional additional evaluation options
func (c Client) IntValueDetails(ctx context.Context, flag string, defaultValue int64, evalCtx EvaluationContext, options EvaluationOptions) (EvaluationDetails, error) {
return c.evaluate(ctx, flag, Int, defaultValue, evalCtx, options)
}

// ObjectValueDetails return object evaluation for flag
func (c Client) ObjectValueDetails(flag string, defaultValue interface{}, evalCtx EvaluationContext, options EvaluationOptions) (EvaluationDetails, error) {
return c.evaluate(flag, Object, defaultValue, evalCtx, options)
// ObjectValueDetails performs a flag evaluation that returns an evaluation details struct.
//
// Parameters:
// - ctx is the standard go context struct used to manage requests (e.g. timeouts)
// - flag is the key that uniquely identifies a particular flag
// - defaultValue is returned if an error occurs
// - evalCtx is the evaluation context used in a flag evaluation (not to be confused with ctx)
// - options are optional additional evaluation options
func (c Client) ObjectValueDetails(ctx context.Context, flag string, defaultValue interface{}, evalCtx EvaluationContext, options EvaluationOptions) (EvaluationDetails, error) {
return c.evaluate(ctx, flag, Object, defaultValue, evalCtx, options)
}

func (c Client) evaluate(
flag string, flagType Type, defaultValue interface{}, evalCtx EvaluationContext, options EvaluationOptions,
ctx context.Context, flag string, flagType Type, defaultValue interface{}, evalCtx EvaluationContext, options EvaluationOptions,
) (EvaluationDetails, error) {
c.logger().V(debug).Info(
"evaluating flag", "flag", flag, "type", flagType.String(), "defaultValue", defaultValue,
Expand Down Expand Up @@ -272,25 +342,25 @@ func (c Client) evaluate(
var resolution InterfaceResolutionDetail
switch flagType {
case Object:
resolution = api.provider.ObjectEvaluation(flag, defaultValue, flatCtx)
resolution = api.provider.ObjectEvaluation(ctx, flag, defaultValue, flatCtx)
case Boolean:
defValue := defaultValue.(bool)
res := api.provider.BooleanEvaluation(flag, defValue, flatCtx)
res := api.provider.BooleanEvaluation(ctx, flag, defValue, flatCtx)
resolution.ResolutionDetail = res.ResolutionDetail
resolution.Value = res.Value
case String:
defValue := defaultValue.(string)
res := api.provider.StringEvaluation(flag, defValue, flatCtx)
res := api.provider.StringEvaluation(ctx, flag, defValue, flatCtx)
resolution.ResolutionDetail = res.ResolutionDetail
resolution.Value = res.Value
case Float:
defValue := defaultValue.(float64)
res := api.provider.FloatEvaluation(flag, defValue, flatCtx)
res := api.provider.FloatEvaluation(ctx, flag, defValue, flatCtx)
resolution.ResolutionDetail = res.ResolutionDetail
resolution.Value = res.Value
case Int:
defValue := defaultValue.(int64)
res := api.provider.IntEvaluation(flag, defValue, flatCtx)
res := api.provider.IntEvaluation(ctx, flag, defValue, flatCtx)
resolution.ResolutionDetail = res.ResolutionDetail
resolution.Value = res.Value
}
Expand Down
11 changes: 6 additions & 5 deletions pkg/openfeature/client_example_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package openfeature_test

import (
"context"
"encoding/json"
"fmt"
"log"
Expand All @@ -17,7 +18,7 @@ func ExampleNewClient() {
func ExampleClient_BooleanValue() {
client := openfeature.NewClient("example-client")
value, err := client.BooleanValue(
"test-flag", true, openfeature.EvaluationContext{}, openfeature.EvaluationOptions{},
context.Background(), "test-flag", true, openfeature.EvaluationContext{}, openfeature.EvaluationOptions{},
)
if err != nil {
log.Fatal("error while getting boolean value : ", err)
Expand All @@ -30,7 +31,7 @@ func ExampleClient_BooleanValue() {
func ExampleClient_StringValue() {
client := openfeature.NewClient("example-client")
value, err := client.StringValue(
"test-flag", "openfeature", openfeature.EvaluationContext{}, openfeature.EvaluationOptions{},
context.Background(), "test-flag", "openfeature", openfeature.EvaluationContext{}, openfeature.EvaluationOptions{},
)
if err != nil {
log.Fatal("error while getting string value : ", err)
Expand All @@ -43,7 +44,7 @@ func ExampleClient_StringValue() {
func ExampleClient_FloatValue() {
client := openfeature.NewClient("example-client")
value, err := client.FloatValue(
"test-flag", 0.55, openfeature.EvaluationContext{}, openfeature.EvaluationOptions{},
context.Background(), "test-flag", 0.55, openfeature.EvaluationContext{}, openfeature.EvaluationOptions{},
)
if err != nil {
log.Fatalf("error while getting float value: %v", err)
Expand All @@ -56,7 +57,7 @@ func ExampleClient_FloatValue() {
func ExampleClient_IntValue() {
client := openfeature.NewClient("example-client")
value, err := client.IntValue(
"test-flag", 3, openfeature.EvaluationContext{}, openfeature.EvaluationOptions{},
context.Background(), "test-flag", 3, openfeature.EvaluationContext{}, openfeature.EvaluationOptions{},
)
if err != nil {
log.Fatalf("error while getting int value: %v", err)
Expand All @@ -69,7 +70,7 @@ func ExampleClient_IntValue() {
func ExampleClient_ObjectValue() {
client := openfeature.NewClient("example-client")
value, err := client.ObjectValue(
"test-flag", map[string]string{"foo": "bar"}, openfeature.EvaluationContext{}, openfeature.EvaluationOptions{},
context.Background(), "test-flag", map[string]string{"foo": "bar"}, openfeature.EvaluationContext{}, openfeature.EvaluationOptions{},
)
if err != nil {
log.Fatal("error while getting object value : ", err)
Expand Down
Loading

0 comments on commit d850c88

Please sign in to comment.