openfeature

package module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 12, 2026 License: MIT Imports: 4 Imported by: 0

README

features-openfeature

The OpenFeature door for go/features. A features.Backend over any openfeature.FeatureProvider, so one adapter opens every vendor that speaks OpenFeature: LaunchDarkly, Unleash (and therefore GitLab Feature Flags), flagd, and the rest.

go get gitlab.com/phpboyscout/go/features-openfeature
import (
    "gitlab.com/phpboyscout/go/features"
    "gitlab.com/phpboyscout/go/features-openfeature"
)

provider := flagd.NewProvider() // any openfeature.FeatureProvider

backend := openfeature.New(provider)
flags := features.Dynamic(set, backend, features.WithInitTimeout(2*time.Second))

if err := flags.Init(ctx); err != nil { /* answers fall back to the set until Ready */ }
defer flags.Close()

dec, err := flags.Evaluate(ctx, "beta-ranking", features.EvalContext{TargetingKey: user})

What it maps

features.Backend OpenFeature provider
Resolve(ctx, id, fallback, ec) BooleanEvaluation(ctx, flag, defaultValue: fallback, flattened ec)
Init(ctx) ContextAwareStateHandler.InitWithContext, else StateHandler.Init, else nothing
Ready() true after Init; cleared by PROVIDER_STALE / PROVIDER_ERROR, restored by PROVIDER_READY
Watch(ctx) PROVIDER_CONFIGURATION_CHANGED forwarded as Change{}; nil for a provider with no EventHandler
Close() ShutdownWithContext, else Shutdown

fallback is the caller's static state. OpenFeature returns it for a flag the provider does not know (FLAG_NOT_FOUND, which Dynamic reports as a fallback with the error) and for a flag that is disabled (reason DISABLED), which this adapter reports as a clean answer whatever error a provider attaches: the fallback applying is exactly what disabled means. Reasons map STATIC/CACHED → static, TARGETING_MATCH/SPLIT → targeting, DISABLED → disabled, ERROR → error, everything else → default; the provider's variant travels on Decision.Variant.

It works at the provider level, not through the SDK's client: no global is set (the SDK's singleton keeps its noop provider), no hooks run, and an evaluation is about three times cheaper. Use the SDK's client instead if you want its hooks.

No vendor provider is linked here; depfootprint_test.go refuses them along with any framework. Your main links the one provider it uses.

Reference: pkg.go.dev.

Licence

MIT. See LICENSE.

Documentation

Overview

Package openfeature adapts an OpenFeature provider to the phpboyscout Go toolkit's feature core: a features.Backend over any openfeature.FeatureProvider, so one adapter opens every vendor that speaks OpenFeature (LaunchDarkly, Unleash and therefore GitLab Feature Flags, flagd, and the rest).

It works at the provider level rather than through the SDK's client, so it touches no global (the SDK's singleton API is never set), carries no hooks and is about three times cheaper per evaluation (go-tool-base spec 0199's spike measured 322 ns against 940 ns). The provider's optional lifecycle and event interfaces map onto Backend's: StateHandler or ContextAwareStateHandler onto Init and Close, EventHandler onto Watch and Ready.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Backend

type Backend struct {
	// contains filtered or unexported fields
}

Backend is a features.Backend over an OpenFeature provider.

func New

func New(provider openfeature.FeatureProvider, opts ...Option) *Backend

New wraps provider as a features.Backend.

func (*Backend) Close

func (b *Backend) Close() error

Close stops the event forwarder and shuts the provider down through whichever state handler it offers.

func (*Backend) Init

func (b *Backend) Init(ctx context.Context) error

Init initialises the provider through whichever state handler it offers (the context-aware one first), then starts forwarding its events when it has any. A provider with no state handler is ready at once.

func (*Backend) Ready

func (b *Backend) Ready() bool

Ready reports whether Init has succeeded and the provider has not since reported itself stale or errored.

func (*Backend) Resolve

func (b *Backend) Resolve(ctx context.Context, id features.ID, fallback bool, ec features.EvalContext) (features.Decision, error)

Resolve asks the provider for a boolean evaluation with the caller's static state as the default value. OpenFeature returns that default for an unknown flag (with FLAG_NOT_FOUND) and for a disabled one (reason DISABLED); the disabled case is a clean answer here, whatever error a provider attaches to it, because the fallback applying is exactly what disabled means.

func (*Backend) Watch

func (b *Backend) Watch(context.Context) <-chan features.Change

Watch returns the change channel, nil until Init and nil for a provider with no events.

type Option

type Option func(*Backend)

Option configures a Backend.

func WithInitContext

func WithInitContext(ec openfeature.EvaluationContext) Option

WithInitContext sets the OpenFeature evaluation context handed to the provider's Init: the global targeting context some vendors want up front.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL