From 20520079341b4cb1f2f37d85d187d73917e78f5f Mon Sep 17 00:00:00 2001 From: Lukas Reining Date: Sat, 30 Dec 2023 18:33:08 +0100 Subject: [PATCH] feat: add context propagation as described in #81 Signed-off-by: Lukas Reining --- specification/glossary.md | 6 ++ .../sections/03-evaluation-context.md | 70 ++++++++++++++++--- 2 files changed, 66 insertions(+), 10 deletions(-) diff --git a/specification/glossary.md b/specification/glossary.md index 3b903d39..57f622dd 100644 --- a/specification/glossary.md +++ b/specification/glossary.md @@ -30,6 +30,7 @@ This document defines some terms that are used across this specification. - [Provider](#provider) - [Integration](#integration) - [Evaluation Context](#evaluation-context) + - [Transaction Context Propagator](#transaction-context-propagator) - [Evaluating Flag Values](#evaluating-flag-values) - [Resolving Flag Values](#resolving-flag-values) - [Flagging specifics](#flagging-specifics) @@ -117,6 +118,11 @@ An SDK-compliant secondary function that is abstracted by the Feature Flag API, Context object for flag evaluation, which may contain information about the runtime environment, details of the transport method encapsulating the flag evaluation, the host, the client, the subject (user), etc. This data may be used as a basis for differential evaluation of feature flags based on rules that can be defined in the flag system. Context data may be provided by merging static global context, arguments to flag evaluation, and implicit language-dependant state propagation mechanisms (thread-local storage, promise chains, continuations, etc). +### Transaction Context Propagator + +An SDK-compliant implementation which stores and returns transaction specific evaluation context. +A transaction can be something like a thread or web request. + ### Evaluating Flag Values The process of retrieving a feature flag value in it's entirety, including: diff --git a/specification/sections/03-evaluation-context.md b/specification/sections/03-evaluation-context.md index 919e0da4..b9f5d10a 100644 --- a/specification/sections/03-evaluation-context.md +++ b/specification/sections/03-evaluation-context.md @@ -88,26 +88,28 @@ See [setting a provider](./01-flag-evaluation.md#setting-a-provider) for details ##### Conditional Requirement 3.2.2.4 -> The API **MUST** have a a mechanism to manage `evaluation context` for an associated name. +> The API **MUST** have a mechanism to manage `evaluation context` for an associated name. In the static-context paradigm, it must be possible to create and remove provider-specific context. See [setting a provider](./01-flag-evaluation.md#setting-a-provider) for details. #### Requirement 3.2.3 -> Evaluation context **MUST** be merged in the order: API (global; lowest precedence) -> client -> invocation -> before hooks (highest precedence), with duplicate values being overwritten. +> Evaluation context **MUST** be merged in the order: API (global; lowest precedence) -> transaction -> client -> invocation -> before hooks (highest precedence), with duplicate values being overwritten. Any fields defined in the client `evaluation context` will overwrite duplicate fields defined globally, and fields defined in the invocation `evaluation context` will overwrite duplicate fields defined globally or on the client. Any resulting `evaluation context` from a [before hook](./04-hooks.md#requirement-434) will overwrite duplicate fields defined globally, on the client, or in the invocation. ```mermaid flowchart LR - global("API (global)") - client("Client") - invocation("Invocation") - hook("Before Hooks") - global --> client - client --> invocation - invocation --> hook + global("API (global)") + transaction("Transaction") + client("Client") + invocation("Invocation") + hook("Before Hooks") + global --> transaction + transaction --> client + client --> invocation + invocation --> hook ``` #### Condition 3.2.4 @@ -128,4 +130,52 @@ The SDK implementation must run the `on context changed` handler on all register > When the `evaluation context` for a specific provider is set, the `on context changed` handler **MUST** only run on the associated provider. -The SDK implementation must run the `on context changed` handler only on the provider that is scoped to the mutated `evaluation context`. \ No newline at end of file +The SDK implementation must run the `on context changed` handler only on the provider that is scoped to the mutated `evaluation context`. + +### 3.3 Context Propagation + +[![experimental](https://img.shields.io/static/v1?label=Status&message=experimental&color=orange)](https://github.com/open-feature/spec/tree/main/specification#experimental) + +#### Condition 3.3.1 + +> The implementation uses the dynamic-context paradigm. + +see: [dynamic-context paradigm](../glossary.md#dynamic-context-paradigm) + +##### Conditional Requirement 3.3.1.1 + +> The API **MUST** have a method for setting a `transaction context propagator`. + +If there already is a `transaction context propagator`, it is replaced with the new one. + +##### Conditional Requirement 3.3.1.2 + +> The API **MUST** have a method for setting the `evaluation context` of the `transaction context propagator`. + +If a `transaction context propagator` is set, this `evaluation context` must be supplied to it and so will be available during the current transaction. +This method can e.g. be used in a request handler to add request specific information to the `evaluation context`. + +##### Conditional Requirement 3.3.1.3 + +> A `transaction context propagator` **MUST** have a method for setting the `evaluation context` of the current transaction. + +A `transaction context propagator` is responsible for persisting context for the duration of a single transaction. +Typically, a transaction context propagator will propagate the context using a language-specific carrier such as [`ThreadLocal` (Java)](https://docs.oracle.com/javase/8/docs/api/java/lang/ThreadLocal.html), [`async hooks` (Node.js)](https://nodejs.org/api/async_hooks.html), [`Context` (Go)](https://pkg.go.dev/context) or another similar mechanism. + +##### Conditional Requirement 3.3.1.4 + +> A `transaction context propagator` **MUST** have a method for getting the `evaluation context` of the current transaction. + +This must be used by the SDK implementation when merging the context for evaluating a feature flag. + +#### Condition 3.3.2 + +> The implementation uses the static-context paradigm. + +see: [static-context paradigm](../glossary.md#static-context-paradigm) + +##### Conditional Requirement 3.3.2.1 + +> The API **MUST NOT** have a method for setting a `transaction context propagator`. + +In the static-context paradigm, context is global, so there should not be different context between transactions.