You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<!-- Please use this template for your pull request. -->
<!-- Please use the sections that you need and delete other sections -->
## This PR
<!-- add the description of the PR here -->
Add support for the hook-data concept for hooks. Hook-data allows for
per-evaluation data to be propagated between hooks.
This is especially useful for analytics purposes where you may want to
measure things that happen between stages, or you want to do something
like create a span in one stage and close it in another.
This concept is similar to the `series data` concept for LaunchDarkly
hooks.
https://github.com/launchdarkly/open-sdk-specs/tree/main/specs/HOOK-hooks#evaluationseriesdata
Unlike `series data` the data in this approach is mutable. This is
because the `before` stage already has a return value. We could
workaround this by specifying a return structure, but it maybe seems
more complex. The data is only passed to a specific hook instance, so
mutability is not of great concern.
Some functional languages may still need to use an immutable with return
values approach.
I can create an OFEP if we think this merits discussion prior to
proposal.
### Related Issues
<!-- add here the GitHub issue that this PR resolves if applicable -->
Related discussion in a PR comment.
open-feature/java-sdk#1049 (comment)
---------
Signed-off-by: Ryan Lamb <[email protected]>
Co-authored-by: Michael Beemer <[email protected]>
Co-authored-by: Lukas Reining <[email protected]>
Co-authored-by: Todd Baert <[email protected]>
Copy file name to clipboardExpand all lines: specification.json
+22-1Lines changed: 22 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -685,7 +685,7 @@
685
685
{
686
686
"id": "Requirement 4.1.1",
687
687
"machine_id": "requirement_4_1_1",
688
-
"content": "Hook context MUST provide: the `flag key`, `flag value type`, `evaluation context`, and the `default value`.",
688
+
"content": "Hook context MUST provide: the `flag key`, `flag value type`, `evaluation context`, `default value`, and `hook data`.",
689
689
"RFC 2119 keyword": "MUST",
690
690
"children": []
691
691
},
@@ -718,6 +718,13 @@
718
718
}
719
719
]
720
720
},
721
+
{
722
+
"id": "Requirement 4.1.5",
723
+
"machine_id": "requirement_4_1_5",
724
+
"content": "The `hook data` MUST be mutable.",
725
+
"RFC 2119 keyword": "MUST",
726
+
"children": []
727
+
},
721
728
{
722
729
"id": "Requirement 4.2.1",
723
730
"machine_id": "requirement_4_2_1",
@@ -761,6 +768,13 @@
761
768
"RFC 2119 keyword": "MUST",
762
769
"children": []
763
770
},
771
+
{
772
+
"id": "Requirement 4.3.2",
773
+
"machine_id": "requirement_4_3_2",
774
+
"content": "`Hook data` MUST must be created before the first `stage` invoked in a hook for a specific evaluation and propagated between each `stage` of the hook. The hook data is not shared between different hooks.",
775
+
"RFC 2119 keyword": "MUST",
776
+
"children": []
777
+
},
764
778
{
765
779
"id": "Condition 4.3.2",
766
780
"machine_id": "condition_4_3_2",
@@ -911,6 +925,13 @@
911
925
"RFC 2119 keyword": "MUST NOT",
912
926
"children": []
913
927
},
928
+
{
929
+
"id": "Requirement 4.6.1",
930
+
"machine_id": "requirement_4_6_1",
931
+
"content": "`hook data` MUST be a structure supporting the definition of arbitrary properties, with keys of type `string`, and values of type `boolean | string | number | datetime | structure`.",
Copy file name to clipboardExpand all lines: specification/sections/04-hooks.md
+104-3Lines changed: 104 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -32,17 +32,20 @@ Hooks can be configured to run globally (impacting all flag evaluations), per cl
32
32
### Definitions
33
33
34
34
**Hook**: Application author/integrator-supplied logic that is called by the OpenFeature framework at a specific stage.
35
-
**Stage**: An explicit portion of the flag evaluation lifecycle. e.g. `before` being "before" the [resolution](../glossary.md#resolving-flag-values) is run.
35
+
36
+
**Stage**: An explicit portion of the flag evaluation lifecycle. e.g. `before` being "before the [resolution](../glossary.md#resolving-flag-values) is run.
37
+
36
38
**Invocation**: A single call to evaluate a flag. `client.getBooleanValue(..)` is an invocation.
39
+
37
40
**API**: The global API singleton.
38
41
39
42
### 4.1. Hook context
40
43
41
-
Hook context exists to provide hooks with information about the invocation.
44
+
Hook context exists to provide hooks with information about the invocation and propagate data between hook stages.
42
45
43
46
#### Requirement 4.1.1
44
47
45
-
> Hook context **MUST** provide: the `flag key`, `flag value type`, `evaluation context`, and the `default value`.
48
+
> Hook context **MUST** provide: the `flag key`, `flag value type`, `evaluation context`, `default value`, and `hook data`.
> `Hook data`**MUST** must be created before the first `stage` invoked in a hook for a specific evaluation and propagated between each `stage` of the hook. The hook data is not shared between different hooks.
115
+
116
+
Example showing data between `before` and `after` stage for two different hooks.
public void after(HookContext context, FlagEvaluationDetails details, HookHints hints) {
322
+
// Only accessible by this hook for this specific evaluation.
323
+
Object value = context.hookData.get("span");
324
+
if (value instanceof Span) {
325
+
Span span = (Span) value;
326
+
span.end();
327
+
}
328
+
}
329
+
```
330
+
331
+
#### Requirement 4.6.1
332
+
333
+
>`hook data`**MUST** be a structure supporting the definition of arbitrary properties, with keys of type `string`, and values of type `boolean | string | number | datetime | structure`.
0 commit comments