Skip to content

Support $.flags context values in segment conditions #226

Description

@khvn26

Dependent flags let a segment condition read another flag's result via a $.flags.<feature name>.<enabled|value|variant> property, so that flag has to be resolved before the condition is evaluated. Behaviour is defined by the shared cases in Flagsmith/engine-test-data#59; schema in Flagsmith/flagsmith#8396; reference implementation in Flagsmith/flagsmith-engine#343.

The reference implementation resolves a flag lazily, on first read, rather than scanning every condition up front to discover dependencies. ojg supports this directly — jp/get.go dispatches on jp.Keyed, so a lazy Flags type resolves on read with no property parsing. Two things in this engine currently get in the way:

  • getContextValue builds its getter per call, so jp.ParseString runs on every lookup — about 20% of a lookup and 10 of its 16 allocations.
  • client.go keeps a single *EngineEvaluationContext in an atomic.Value, shared across goroutines. Resolved flags written onto that struct would be written concurrently by every in-flight evaluation.

For reference, pre-resolving all flags instead costs a flat ~12 µs and ~49 KB per evaluation, against ~400 ns per flag actually read; lazy resolution via jp.Keyed and via parsed-Expr inspection measure the same, so either is fine.

Acceptance criteria

Engine:

  • engine-test-data is bumped to the tag containing the flag dependency cases, and they pass.
  • An environment with no $.flags conditions gains no per-evaluation cost.
  • Resolved flags are held per evaluation, never written to the context shared via atomic.Value.
  • Parsed JSONPath expressions are cached per property string.

SDK:

  • GetFlags does not skip segments anymore.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions