Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into fix/file-exporter-pat…
Browse files Browse the repository at this point in the history
…h-handling
  • Loading branch information
thomaspoignant committed Oct 12, 2024
2 parents e2fa717 + 427c5d8 commit d73b90c
Show file tree
Hide file tree
Showing 88 changed files with 5,543 additions and 74 deletions.
12 changes: 7 additions & 5 deletions cmd/relayproxy/api/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,12 @@ func (s *Server) Start() {
}

// start the OpenTelemetry tracing service
err := s.otelService.Init(context.Background(), *s.config)
if err != nil {
s.zapLog.Error("error while initializing Otel", zap.Error(err))
// we can continue because otel is not mandatory to start the server
if s.config.OpenTelemetryOtlpEndpoint != "" {
err := s.otelService.Init(context.Background(), *s.config)
if err != nil {
s.zapLog.Error("error while initializing Otel", zap.Error(err))
// we can continue because otel is not mandatory to start the server
}
}

// starting the main application
Expand All @@ -136,7 +138,7 @@ func (s *Server) Start() {
zap.String("address", address),
zap.String("version", s.config.Version))

err = s.apiEcho.Start(address)
err := s.apiEcho.Start(address)
if err != nil && !errors.Is(err, http.ErrServerClosed) {
s.zapLog.Fatal("Error starting relay proxy", zap.Error(err))
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/relayproxy/helm-charts/relay-proxy/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ sources:
- "https://github.com/thomaspoignant/go-feature-flag"
description: A Helm chart to deploy go-feature-flag-relay proxy into Kubernetes
type: application
version: 1.36.0
appVersion: "v1.36.0"
version: 1.36.1
appVersion: "v1.36.1"
icon: https://raw.githubusercontent.com/thomaspoignant/go-feature-flag/main/logo.png
maintainers:
- name: thomaspoignant
Expand Down
2 changes: 1 addition & 1 deletion cmd/relayproxy/helm-charts/relay-proxy/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# relay-proxy

![Version: 1.36.0](https://img.shields.io/badge/Version-1.36.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.36.0](https://img.shields.io/badge/AppVersion-v1.36.0-informational?style=flat-square)
![Version: 1.36.1](https://img.shields.io/badge/Version-1.36.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: v1.36.1](https://img.shields.io/badge/AppVersion-v1.36.1-informational?style=flat-square)

A Helm chart to deploy go-feature-flag-relay proxy into Kubernetes

Expand Down
30 changes: 0 additions & 30 deletions website/docs/openfeature_sdk/server_providers/openfeature_go.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -88,35 +88,5 @@ if adminFlag {
}
```

## Unit testing

When testing code that relies on feature flags, it's crucial to have control over the flag values to simulate different scenarios and isolate your tests.

The **OpenFeature in-memory provider** offers a convenient solution by allowing you to define and manipulate feature flag values directly within your tests.
This eliminates the need to start a relay-proxy and provides a more efficient and flexible testing environment.

In this example, we demonstrate how to use the in-memory provider to set the value of 2 different feature flags in a test:

```go
func TestMyTest(t *testing.T) {
apiInstance := openfeature.GetApiInstance()
apiInstance.SetProvider(
memprovider.NewInMemoryProvider(
map[string]memprovider.InMemoryFlag{
"my-flag-1": {Key: "my-flag-1", DefaultVariant: "var_a", Variants: map[string]any{"var_a": true}},
"my-flag-2": {Key: "my-flag-2", DefaultVariant: "disabled", Variants: map[string]any{"disabled": false}},
}
))

// Your test code here
}
```
By setting the in memory provider you are able to predict the value of the flag you will get when running your tests.
This is a good way to ensure that your test is using the value you are expecting as response of your feature flag.

:::note
The in memory provider is part of the OpenFeature SDK, you don't need to export any extra dependencies to use it.
:::

## Contribute to the provider
You can find the source of the provider in the [`open-feature/go-sdk-contrib`](https://github.com/open-feature/go-sdk-contrib/tree/main/providers/go-feature-flag) repository.
6 changes: 3 additions & 3 deletions website/docs/relay_proxy/configure_relay_proxy.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,13 +200,13 @@ the [doc](../go_module/store_file/redis#expected-format) available._
| Field name | Type | Default | Description |
|---------------------------|--------|------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `kind` | string | **none** | **(mandatory)** Value should be **`file`**.<br/>_This field is mandatory and describes which retriever you are using._ |
| `outputDir` | string | **none** | **(mandatory)** OutputDir is the location of the directory where to store the exported files. |
| `outputDir` | string | **none** | **(mandatory)** OutputDir is the location of the directory where to store the exported files. |
| `flushInterval` | int | `60000` | The interval in millisecond between 2 calls to the webhook _(if the `maxEventInMemory` is reached before the flushInterval we will call the webhook before)_. |
| `maxEventInMemory` | int | `100000` | If we hit that limit we will call the webhook. |
| `format` | string | `JSON` | Format is the output format you want in your exported file. Available format: `JSON`, `CSV`, `Parquet`. |
| `filename` | string | `flag-variation-{{ .Hostname}}-{{ .Timestamp}}.{{ .Format}}` | You can use a templated config to define the name of your exported files. Available replacements are `{{ .Hostname}}`, `{{ .Timestamp}}` and `{{ .Format}` |
| `csvTemplate` | string | `{{ .Kind}};{{ .ContextKind}};{{ .UserKey}};{{ .CreationDate}};{{ .Key}};{{ .Variation}};{{ .Value}};{{ .Default}};{{ .Source}}\n` | CsvTemplate is used if your output format is CSV.<br/>This field will be ignored if you are using format other than CSV.<br/>You can decide which fields you want in your CSV line with a go-template syntax, please check [`internal/exporter/feature_event.go`](https://github.com/thomaspoignant/go-feature-flag/blob/main/internal/exporter/feature_event.go) to see the fields available. |`
| `parquetCompressionCodec` | string | `SNAPPY` | ParquetCompressionCodec is the parquet compression codec for better space efficiency. [Available options](https://github.com/apache/parquet-format/blob/master/Compression.md) |`
| `csvTemplate` | string | `{{ .Kind}};{{ .ContextKind}};{{ .UserKey}};{{ .CreationDate}};{{ .Key}};{{ .Variation}};{{ .Value}};{{ .Default}};{{ .Source}}\n` | CsvTemplate is used if your output format is CSV.<br/>This field will be ignored if you are using format other than CSV.<br/>You can decide which fields you want in your CSV line with a go-template syntax, please check [`internal/exporter/feature_event.go`](https://github.com/thomaspoignant/go-feature-flag/blob/main/internal/exporter/feature_event.go) to see the fields available. |
| `parquetCompressionCodec` | string | `SNAPPY` | ParquetCompressionCodec is the parquet compression codec for better space efficiency. [Available options](https://github.com/apache/parquet-format/blob/master/Compression.md) |

### Log

Expand Down
37 changes: 7 additions & 30 deletions website/docs/relay_proxy/deploy_relay_proxy.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ description: Deploy the relay proxy.

# Deploy the relay proxy

## Deploy in Kubernetes using Helm

## Deploy in Kubernetes using Helm
The relay proxy can be deployed in Kubernetes using a helm chart.
Helm is an invaluable tool for configuring and deploying applications to a Kubernetes environment.

Expand All @@ -28,11 +27,8 @@ helm repo add go-feature-flag https://charts.gofeatureflag.org/

### Step 2: Install the Chart

Install the Helm Chart with the Helm install command and provide the custom repository name, the chart name and any
necessary values files.
You can look at
the [helm doc](https://github.com/thomaspoignant/go-feature-flag/blob/main/cmd/relayproxy/helm-charts/relay-proxy/README.md)
to know exactly what you can change in the values.yaml file.
Install the Helm Chart with the Helm install command and provide the custom repository name, the chart name and any necessary values files.
You can look at the [helm doc](https://github.com/thomaspoignant/go-feature-flag/blob/main/cmd/relayproxy/helm-charts/relay-proxy/README.md) to know exactly what you can change in the values.yaml file.

```shell
helm install go-feature-flag/relay-proxy -f values.yaml
Expand All @@ -47,7 +43,6 @@ helm list
```

## Deploy as AWS Lambda

The GO Feature Flag relay proxy can easily be launched as an AWS Lambda function.
To do this, simply set the `startAsAwsLambda` option in your configuration file to `true`, like so:

Expand All @@ -56,34 +51,16 @@ To do this, simply set the `startAsAwsLambda` option in your configuration file
startAsAwsLambda: true
```
Once you've updated your configuration file, you can deploy your function in AWS and configure it to be accessible
via HTTP. This can be achieved by creating an API Gateway or an Application Load Balancer (ALB) and linking it to
Once you've updated your configuration file, you can deploy your function in AWS and configure it to be accessible
via HTTP. This can be achieved by creating an API Gateway or an Application Load Balancer (ALB) and linking it to
your Lambda function.
By configuring your GO Feature Flag relay proxy to run as an AWS Lambda function, you can take advantage of many
benefits of serverless computing, including automatic scaling, reduced infrastructure costs, and simplified
benefits of serverless computing, including automatic scaling, reduced infrastructure costs, and simplified
deployment and management.
:::info
As part of our release process, we are building an archive ready to be deployed as AWS lambda.
You can find it in the [GitHub release page](https://github.com/thomaspoignant/go-feature-flag/releases),and you can use
the assets named `go-feature-flag-aws-lambda_<version>.zip`.
You can find it in the [GitHub release page](https://github.com/thomaspoignant/go-feature-flag/releases),and you can use the assets named `go-feature-flag-aws-lambda_<version>.zip`.
:::

### Choose the handler for your AWS Lambda

Depending on what you put in front of your Lambda function, you will need to choose the right handler.
GO Feature Flag supports 3 different handlers:

- `APIGatewayV1`: This handler is used when you put an API Gateway with the v1 format in front of your Lambda function.
- `APIGatewayV2`: This handler is used when you put an API Gateway with the v2 format in front of your Lambda function.
- `ALB`: This handler is used when you put an Application Load Balancer in front of your Lambda function.

To choose the right handler, you need to set the `awsLambdaAdapter` option in your configuration file with one of this
value. If you don't set this option, the default value is `APIGatewayV2`.

```yaml
# ...
startAsAwsLambda: true
awsLambdaAdapter: ALB
```
2 changes: 1 addition & 1 deletion website/static/sdk-versions.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"maven":{"sdk":"1.12.0","providerKt":"0.1.0","providerJava":"0.3.0","android":"0.3.0"},"npm":{"core":"1.4.0","serverSDK":"1.15.1","providerServer":"0.7.3","providerWeb":"0.2.1"},"pypi":{"sdk":"0.7.1","provider":"0.2.1"},"nuget":{"sdk":"2.0.0","provider":"0.2.0"},"go":{"provider":"v0.2.1","sdk":"v1.13.0"}}
{"maven":{"sdk":"1.12.0","providerKt":"0.1.0","providerJava":"0.3.0","android":"0.3.0"},"npm":{"core":"1.4.0","serverSDK":"1.15.1","webSDK":"1.2.4","providerWeb":"0.2.1"},"pypi":{"sdk":"0.7.1","provider":"0.2.1"},"nuget":{"sdk":"2.0.0","provider":"0.2.0"},"go":{"provider":"v0.2.1","sdk":"v1.13.0"}}
5 changes: 5 additions & 0 deletions website/versioned_docs/version-v1.36.1/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"position": 0,
"collapsible": true,
"collapsed": false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"position": 20,
"collapsible": true,
"collapsed": true,
"label": "Configure your feature flags",
"link": {
"type": "generated-index",
"title": "Configure your feature flags"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
sidebar_position: 22
description: How to bucket users based on a custom identifier
---

# Custom bucketing

When evaluating flags, the `targetingKey` is usually given a user ID. This key ensures that a user will always be in the same group for each flag.

Sometimes, it is desireable to _bucket_ users based on a different value. The `bucketingKey` field in the flag configuration allows you to define a different identifier to be used instead. For example:

```yaml
first-flag:
bucketingKey: "teamId"
variations:
A: false
B: true
defaultRule: # When no targeting match we use the defaultRule
percentage:
A: 50
B: 50
```
With this flag configuration, the `teamId` value will be used for hashing instead of `targetingKey`. The value must be provided to the evaluation context:


```go
user = ffcontext.NewEvaluationContextBuilder("user126")
.AddCustom("teamId", "f74b72")
.Build()
ffclient.BoolVariation("first-flag", user, false)
```

As a result, users who are members of the same team will receive the same flag variation, consistently. A different `bucketingKey` can be used per experiment, though normally you'll only have a handful of possible values.

This is useful for A/B testing, permissions management and other use cases where targeting a consistent group of users is required.

**Note**: if a value in the corresponding `bucketingKey` is not found in the evaluation context, the flag rules will not be evaluated, and the SDK will return the default value.
Loading

0 comments on commit d73b90c

Please sign in to comment.