Skip to content

Commit 42340bb

Browse files
authored
fix: clarify hook ordering (#315)
This clarifies some ambiguity in hook execution order, mentioned in #164: > The issue here is that the overall hook execution order would vary if any of these hooks have more than one entry. For example: > > ``` > API = [A, B] > Client = [C, D] > Invocation = [E, F] > Provider = [G, H] > > # `before` list > before_hooks = API + Client + Invocation + Provider > > # spreading directly (like Python) > list1 = Provider + Invocation + Client + API > # results in [G, H, E, F, C, D, A, B] > > # reversing the before list (like JavaScript) > list2 = before_hooks[:] > list2.reverse() > # results in [H, G, F, E, D, C, B, A] > ``` This change makes clear that `[H, G, F, E, D, C, B, A]` is the correct answer here, which is the more intuitive choice, in my opinion. This is also one of the few (only?) normative spec points that isn't a single sentence, but instead has point-form clauses, so I've also attempted to fix that. I've work-shopped this with a few people and they interpreted it correctly, though admittedly, the term "stack-wise" is doing a lot of work here. I'm hopeful that our audience is familiar enough with that sort of term that the intent is clear. I believe there's a few SDKs where this is incorrectly implemented, I'll audit those and create issues if this is merged. I don't expect that such an implementation change will significantly impact anyone. --------- Signed-off-by: Todd Baert <[email protected]>
1 parent cbfa0a9 commit 42340bb

File tree

2 files changed

+19
-7
lines changed

2 files changed

+19
-7
lines changed

specification.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -865,7 +865,7 @@
865865
{
866866
"id": "Requirement 4.4.2",
867867
"machine_id": "requirement_4_4_2",
868-
"content": "Hooks MUST be evaluated in the following order: - before: API, Client, Invocation, Provider - after: Provider, Invocation, Client, API - error (if applicable): Provider, Invocation, Client, API - finally: Provider, Invocation, Client, API",
868+
"content": "Hooks MUST be executed \"stack-wise\" with respect to flag resolution, prioritizing increasing specificity (API, Client, Invocation, Provider) first, and the order in which they were added second.",
869869
"RFC 2119 keyword": "MUST",
870870
"children": []
871871
},

specification/sections/04-hooks.md

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -246,12 +246,24 @@ client.getValue('my-flag', 'defaultValue', new Hook3());
246246

247247
#### Requirement 4.4.2
248248

249-
> Hooks **MUST** be evaluated in the following order:
250-
>
251-
> - before: API, Client, Invocation, Provider
252-
> - after: Provider, Invocation, Client, API
253-
> - error (if applicable): Provider, Invocation, Client, API
254-
> - finally: Provider, Invocation, Client, API
249+
> Hooks **MUST** be executed "stack-wise" with respect to flag resolution, prioritizing increasing specificity (API, Client, Invocation, Provider) first, and the order in which they were added second.
250+
251+
Before flag resolution (the `before` stage), hooks run in the order `API` -> `Client` -> `Invocation` -> `Provider`, and within those, in the order in which they were added.
252+
After flag evaluation (the `after`, `error`, or `finally` stages), hooks run in the order `Provider` -> `Invocation` -> `Client` -> `API`, and within those, in reverse of the order in which they were added.
253+
This achieves intuitive "stack-like" or "LIFO" behavior for side effects and transformations.
254+
255+
```
256+
Given hooks A - H, each implementing the both the `before` and `after` stages, added at the following levels and order:
257+
258+
API: [A, B]
259+
Client: [C, D]
260+
Invocation: [E, F]
261+
Provider: [G, H]
262+
263+
The expected order of execution is:
264+
265+
A.before -> B.before -> C.before -> D.before -> E.before -> F.before -> G.before -> H.before -> flagResolution -> H.after -> G.after -> F.after -> E.after -> D.after -> C.after -> B.after -> A.after
266+
```
255267
256268
#### Requirement 4.4.3
257269

0 commit comments

Comments
 (0)