Skip to content

Commit 52cbaa7

Browse files
committed
feat: performance boost
Signed-off-by: Simon Schrottner <[email protected]>
1 parent 1de7aea commit 52cbaa7

File tree

5 files changed

+50
-14
lines changed

5 files changed

+50
-14
lines changed

src/main/java/dev/openfeature/sdk/HookContext.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ public interface HookContext<T> {
1818
* @param defaultValue Fallback value
1919
* @param <T> type that the flag is evaluating against
2020
* @return resulting context for hook
21+
*
22+
* @deprecated this should not be instantiated outside the SDK anymore
2123
*/
24+
@Deprecated
2225
static <T> HookContext<T> from(
2326
String key,
2427
FlagValueType type,
Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,63 @@
11
package dev.openfeature.sdk;
22

3+
import lombok.AccessLevel;
34
import lombok.Builder;
5+
import lombok.Data;
6+
import lombok.Getter;
47
import lombok.NonNull;
8+
import lombok.Setter;
59
import lombok.Value;
610
import lombok.With;
11+
import lombok.experimental.NonFinal;
712

813
/**
914
* A data class to hold immutable context that {@link Hook} instances use.
1015
*
1116
* @param <T> the type for the flag being evaluated
1217
*/
13-
@Value
18+
@Data
1419
@Builder
1520
@With
21+
@Setter(AccessLevel.PRIVATE)
1622
class HookContextWithoutData<T> implements HookContext<T> {
1723
@NonNull String flagKey;
1824

1925
@NonNull FlagValueType type;
2026

2127
@NonNull T defaultValue;
2228

29+
@Setter(AccessLevel.PACKAGE)
2330
@NonNull EvaluationContext ctx;
2431

2532
ClientMetadata clientMetadata;
2633
Metadata providerMetadata;
34+
35+
/**
36+
* Builds a {@link HookContextWithoutData} instances from request data.
37+
*
38+
* @param key feature flag key
39+
* @param type flag value type
40+
* @param clientMetadata info on which client is calling
41+
* @param providerMetadata info on the provider
42+
* @param ctx Evaluation Context for the request
43+
* @param defaultValue Fallback value
44+
* @param <T> type that the flag is evaluating against
45+
* @return resulting context for hook
46+
*/
47+
static <T> HookContextWithoutData<T> from(
48+
String key,
49+
FlagValueType type,
50+
ClientMetadata clientMetadata,
51+
Metadata providerMetadata,
52+
EvaluationContext ctx,
53+
T defaultValue) {
54+
return HookContextWithoutData.<T>builder()
55+
.flagKey(key)
56+
.type(type)
57+
.clientMetadata(clientMetadata)
58+
.providerMetadata(providerMetadata)
59+
.ctx(ImmutableContext.EMPTY)
60+
.defaultValue(defaultValue)
61+
.build();
62+
}
2763
}

src/main/java/dev/openfeature/sdk/ImmutableContext.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
@SuppressWarnings("PMD.BeanMembersShouldSerialize")
2121
public final class ImmutableContext implements EvaluationContext {
2222

23+
public static final ImmutableContext EMPTY = new ImmutableContext();
24+
2325
@Delegate(excludes = DelegateExclusions.class)
2426
private final ImmutableStructure structure;
2527

src/main/java/dev/openfeature/sdk/OpenFeatureClient.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -166,22 +166,23 @@ private <T> FlagEvaluationDetails<T> evaluateFlag(
166166
FlagEvaluationDetails<T> details = null;
167167
List<Hook> mergedHooks;
168168
List<Pair<Hook, HookData>> hookDataPairs = null;
169-
HookContext<T> hookContext = null;
169+
HookContextWithoutData<T> hookContext = null;
170170

171171
try {
172172
final var stateManager = openfeatureApi.getFeatureProviderStateManager(this.domain);
173173
// provider must be accessed once to maintain a consistent reference
174174
final var provider = stateManager.getProvider();
175175
final var state = stateManager.getState();
176-
hookContext = HookContext.from(
177-
key, type, this.getMetadata(), provider.getMetadata(), mergeEvaluationContext(ctx), defaultValue);
176+
hookContext = HookContextWithoutData.from(
177+
key, type, this.getMetadata(), provider.getMetadata(), null, defaultValue);
178+
179+
hookContext.setCtx(mergeEvaluationContext(ctx));
180+
178181
mergedHooks = ObjectUtils.merge(
179182
provider.getProviderHooks(), flagOptions.getHooks(), clientHooks, openfeatureApi.getMutableHooks());
180183
hookDataPairs = hookSupport.getHookDataPairs(mergedHooks, type);
181184
var mergedCtx = hookSupport.beforeHooks(type, hookContext, hookDataPairs, hints);
182-
183-
hookContext =
184-
HookContext.from(key, type, this.getMetadata(), provider.getMetadata(), mergedCtx, defaultValue);
185+
hookContext.setCtx(mergedCtx);
185186

186187
// "short circuit" if the provider is in NOT_READY or FATAL state
187188
if (ProviderState.NOT_READY.equals(state)) {

src/test/java/dev/openfeature/sdk/HookContextTest.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,7 @@ void shouldCreateHookContextWithHookData() {
3535
HookData hookData = HookData.create();
3636
hookData.set("test", "value");
3737

38-
HookContext<String> context = HookContext.<String>builder()
39-
.flagKey("test-flag")
40-
.type(FlagValueType.STRING)
41-
.defaultValue("default")
42-
.ctx(new ImmutableContext())
43-
.hookData(hookData)
44-
.build();
38+
HookContext<String> context = HookContextWithData.of(null, hookData);
4539

4640
assertNotNull(context.getHookData());
4741
assertEquals("value", context.getHookData().get("test"));

0 commit comments

Comments
 (0)