Skip to content

Commit bfb10a3

Browse files
thomaspoignantrenovate[bot]toddbaertgithub-actions[bot]zdunecki
authored
feat(go-feature-flag)!: Introduce in-process evaluation + tracking (#1365)
Signed-off-by: Thomas Poignant <[email protected]> Signed-off-by: Todd Baert <[email protected]> Signed-off-by: Patryk Zdunowski <[email protected]> Signed-off-by: Ryan Lamb <[email protected]> Signed-off-by: Adam Simon <[email protected]> Signed-off-by: wadii <[email protected]> Signed-off-by: Michael Beemer <[email protected]> Signed-off-by: Giovanni De Giorgio <[email protected]> Signed-off-by: Lukas Reining <[email protected]> Signed-off-by: Jonathan Norris <[email protected]> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Todd Baert <[email protected]> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Patryk Zdunowski <[email protected]> Co-authored-by: Ryan Lamb <[email protected]> Co-authored-by: adams85 <[email protected]> Co-authored-by: Adam Simon <[email protected]> Co-authored-by: Zaimwa9 <[email protected]> Co-authored-by: Michael Beemer <[email protected]> Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Co-authored-by: Giovanni De Giorgio <[email protected]> Co-authored-by: Zaimwa9 <[email protected]> Co-authored-by: Lukas Reining <[email protected]> Co-authored-by: Jonathan Norris <[email protected]>
1 parent 3637aa1 commit bfb10a3

File tree

111 files changed

+9444
-2028
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

111 files changed

+9444
-2028
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,6 @@
1717
[submodule "libs/shared/flagd-core/spec"]
1818
path = libs/shared/flagd-core/spec
1919
url = https://github.com/open-feature/spec
20+
[submodule "libs/providers/go-feature-flag/wasm-releases"]
21+
path = libs/providers/go-feature-flag/wasm-releases
22+
url = https://github.com/go-feature-flag/wasm-releases.git

libs/providers/go-feature-flag/.eslintrc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"extends": ["../../../.eslintrc.json"],
3-
"ignorePatterns": ["!**/*"],
3+
"ignorePatterns": ["!**/*", "src/lib/wasm/wasm_exec.js"],
44
"rules": {
55
"@typescript-eslint/no-explicit-any": "off",
66
"quotes": ["error", "single"]
Lines changed: 205 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,215 @@
1-
# Server-side Go Feature Flag Provider
1+
# Server-side GO Feature Flag Provider
22

3-
This provider is an implementation for [`go-feature-flag`](https://github.com/thomaspoignant/go-feature-flag) a simple and complete
4-
feature flag solution, without any complex backend system to install, all you need is a file as your backend.
3+
A feature flag provider for [OpenFeature](https://openfeature.dev/) that integrates with [go-feature-flag](https://github.com/thomaspoignant/go-feature-flag), a simple and complete feature flag solution.
54

6-
It uses [`go-feature-flag-relay-proxy`](https://github.com/thomaspoignant/go-feature-flag-relay-proxy) which expose the capabilities of the SDK through an API layer.
5+
This provider supports both **in-process** and **remote** evaluation modes, offering flexibility for different deployment scenarios.
76

8-
## Installation
7+
## Features 🚀
98

9+
- **Dual Evaluation Modes**: In-process evaluation for performance and remote evaluation for centralized control
10+
- **Real-time Configuration Updates**: Automatic polling for flag configuration changes
11+
- **Comprehensive Data Collection**: Built-in event tracking and analytics
12+
- **Flexible Context Support**: Rich evaluation context with targeting rules
13+
- **Caching**: Intelligent caching with automatic cache invalidation
14+
- **Error Handling**: Robust error handling with fallback mechanisms
15+
- **TypeScript Support**: Full TypeScript support with type safety
16+
- **OpenFeature Compliance**: Full compliance with OpenFeature specification
17+
18+
## Installation 📦
19+
20+
```bash
21+
npm install @openfeature/go-feature-flag-provider
22+
```
23+
24+
### Peer Dependencies
25+
26+
```bash
27+
npm install @openfeature/server-sdk
28+
```
29+
30+
## Quick Start 🏃‍♂️
31+
32+
### Basic Setup
33+
34+
```typescript
35+
import { OpenFeature } from '@openfeature/server-sdk';
36+
import { GoFeatureFlagProvider, EvaluationType } from '@openfeature/go-feature-flag-provider';
37+
38+
// Initialize the provider
39+
const provider = new GoFeatureFlagProvider({
40+
endpoint: 'https://your-relay-proxy.com',
41+
evaluationType: EvaluationType.Remote,
42+
});
43+
44+
// Register the provider
45+
OpenFeature.setProvider(provider);
46+
47+
// Get a client
48+
const client = OpenFeature.getClient();
49+
50+
// Evaluate a flag
51+
const flagValue = await client.getBooleanValue('my-feature-flag', false, {
52+
targetingKey: 'user-123',
53+
54+
});
55+
```
56+
57+
### In-Process Evaluation
58+
59+
For high-performance scenarios where you want to evaluate flags locally:
60+
61+
```typescript
62+
import { GoFeatureFlagProvider, EvaluationType } from '@openfeature/go-feature-flag-provider';
63+
64+
const provider = new GoFeatureFlagProvider({
65+
endpoint: 'https://your-relay-proxy.com',
66+
evaluationType: EvaluationType.InProcess,
67+
flagChangePollingIntervalMs: 30000, // Poll every 30 seconds
68+
});
69+
```
70+
71+
## Configuration Options ⚙️
72+
73+
### Provider Options
74+
75+
| Option | Type | Default | Description |
76+
| ----------------------------- | ------------------ | ------------ | ----------------------------------------------- |
77+
| `endpoint` | `string` | **Required** | The endpoint of the GO Feature Flag relay-proxy |
78+
| `evaluationType` | `EvaluationType` | `InProcess` | Evaluation mode: `InProcess` or `Remote` |
79+
| `timeout` | `number` | `10000` | HTTP request timeout in milliseconds |
80+
| `flagChangePollingIntervalMs` | `number` | `120000` | Polling interval for configuration changes |
81+
| `dataFlushInterval` | `number` | `120000` | Data collection flush interval |
82+
| `maxPendingEvents` | `number` | `10000` | Maximum pending events before flushing |
83+
| `disableDataCollection` | `boolean` | `false` | Disable data collection entirely |
84+
| `apiKey` | `string` | `undefined` | API key for authentication |
85+
| `exporterMetadata` | `ExporterMetadata` | `undefined` | Custom metadata for events |
86+
| `fetchImplementation` | `FetchAPI` | `undefined` | Custom fetch implementation |
87+
88+
### Evaluation Types
89+
90+
#### InProcess Evaluation
91+
92+
- **Performance**: Fastest evaluation with local caching
93+
- **Network**: Minimal network calls, only for configuration updates and tracking
94+
- **Use Case**: High-performance applications, real-time evaluation
95+
96+
#### Remote Evaluation
97+
98+
- **Performance**: Network-dependent evaluation
99+
- **Network**: Each evaluation requires a network call, works well with side-cars or in the edge
100+
- **Use Case**: Centralized control
101+
102+
## Advanced Usage 🔧
103+
104+
### Custom Context and Targeting
105+
106+
```typescript
107+
const context = {
108+
targetingKey: 'user-123',
109+
110+
firstname: 'John',
111+
lastname: 'Doe',
112+
anonymous: false,
113+
professional: true,
114+
rate: 3.14,
115+
age: 30,
116+
company_info: {
117+
name: 'my_company',
118+
size: 120,
119+
},
120+
labels: ['pro', 'beta'],
121+
};
122+
123+
const flagValue = await client.getBooleanValue('my-feature-flag', false, context);
124+
```
125+
126+
### Data Collection and Analytics
127+
128+
The provider automatically collects evaluation data. You can customize this behavior:
129+
130+
```typescript
131+
const provider = new GoFeatureFlagProvider({
132+
endpoint: 'https://your-relay-proxy.com',
133+
evaluationType: EvaluationType.Remote,
134+
disableDataCollection: false, // Enable data collection
135+
dataFlushInterval: 20000, // Flush every 20 seconds
136+
maxPendingEvents: 5000, // Max 5000 pending events
137+
});
138+
```
139+
140+
### Custom Exporter Metadata
141+
142+
Add custom metadata to your evaluation events:
143+
144+
```typescript
145+
import { ExporterMetadata } from '@openfeature/go-feature-flag-provider';
146+
147+
const metadata = new ExporterMetadata()
148+
.add('environment', 'production')
149+
.add('version', '1.0.0')
150+
.add('region', 'us-east-1');
151+
152+
const provider = new GoFeatureFlagProvider({
153+
endpoint: 'https://your-relay-proxy.com',
154+
evaluationType: EvaluationType.Remote,
155+
exporterMetadata: metadata,
156+
});
157+
```
158+
159+
## Flag Types Supported 🎯
160+
161+
The provider supports all OpenFeature flag types:
162+
163+
### Boolean Flags
164+
165+
```typescript
166+
const isEnabled = await client.getBooleanValue('feature-flag', false, context);
167+
const details = await client.getBooleanDetails('feature-flag', false, context);
10168
```
11-
$ npm install @openfeature/go-feature-flag-provider
169+
170+
### String Flags
171+
172+
```typescript
173+
const message = await client.getStringValue('welcome-message', 'Hello!', context);
174+
const details = await client.getStringDetails('welcome-message', 'Hello!', context);
12175
```
13176

14-
Required peer dependencies
177+
### Number Flags
15178

179+
```typescript
180+
const percentage = await client.getNumberValue('discount-percentage', 0, context);
181+
const details = await client.getNumberDetails('discount-percentage', 0, context);
16182
```
17-
$ npm install @openfeature/server-sdk
183+
184+
### Object Flags
185+
186+
```typescript
187+
const config = await client.getObjectValue('user-config', {}, context);
188+
const details = await client.getObjectDetails('user-config', {}, context);
18189
```
190+
191+
## Tracking Events 📊
192+
193+
The provider supports custom event tracking:
194+
195+
```typescript
196+
// Track a custom event
197+
client.track('user_action', context, {
198+
action: 'button_click',
199+
page: 'homepage',
200+
timestamp: Date.now(),
201+
});
202+
```
203+
204+
## Contributing 🤝
205+
206+
We welcome contributions! Please see our [contributing guidelines](CONTRIBUTING.md) for details.
207+
208+
## License 📄
209+
210+
This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details.
211+
212+
## Support 💬
213+
214+
- **Documentation**: [GO Feature Flag Documentation](https://gofeatureflag.org/), [OpenFeature Documentation](https://openfeature.dev/)
215+
- **Issues**: [GitHub Issues](https://github.com/thomaspoignant/go-feature-flag/issues)

libs/providers/go-feature-flag/jest.config.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
export default {
33
displayName: 'provider-go-feature-flag',
44
preset: '../../../jest.preset.js',
5-
globals: {
6-
'ts-jest': {
7-
tsconfig: '<rootDir>/tsconfig.spec.json',
8-
},
9-
},
105
transform: {
11-
'^.+\\.[tj]s$': 'ts-jest',
6+
'^.+\\.ts$': [
7+
'ts-jest',
8+
{
9+
tsconfig: '<rootDir>/tsconfig.spec.json',
10+
},
11+
],
1212
},
1313
moduleFileExtensions: ['ts', 'js', 'html'],
1414
coverageDirectory: '../../../coverage/libs/providers/go-feature-flag',

0 commit comments

Comments
 (0)