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
The OpenFeature specification now includes support for hook data, which allows hooks to maintain state across their execution stages (before → after/error → finally). This feature enables use cases like distributed tracing, performance monitoring, and multi-stage validation.
This issue tracks the implementation of hook data support in this SDK to achieve compliance with the latest specification.
Action Required
SDK maintainers need to implement hook data support according to the specification defined in:
Hook data specification enables stateful hook operations
The OpenFeature hook data specification provides a mechanism for different stages of the same hook to share state during a single flag evaluation. This feature supports implementing telemetry, performance monitoring, and resource management use cases. The .NET SDK's implementation in open-feature/dotnet-sdk#387 demonstrates a successful approach that other SDKs can follow.
Hook data provides the ability for hooks to maintain state across their execution lifecycle. When a hook starts an operation in the before stage (like opening a telemetry span), it needs a way to access that same data in the after stage to complete the operation. Without hook data, developers resort to workarounds like global state, weak maps, or thread-local storage, which introduce complexity and potential bugs.
The specification defines hook data as a mutable, per-hook, per-evaluation data structure. This scoping means each hook instance gets its own isolated data store that persists only for the duration of a single flag evaluation. Different hooks evaluating the same flag don't share data, preventing interference and ensuring predictable behavior.
Core specification requirements
Data structure and access patterns
Hook data MUST be implemented as a structure supporting arbitrary properties with string keys and values of any type. The structure must be mutable to allow stages to modify shared state. SDKs typically implement this as a map-like interface with set(key, value) and get(key) methods.
The data structure must be created before the first hook stage executes and remain available throughout all stages (before → after/error → finally). This lifecycle management is the SDK's responsibility, not the hook developer's.
Isolation and scoping guarantees
Each hook instance maintains its own hook data - there's no sharing between different hooks. This isolation extends to:
Different hook types running for the same evaluation
Multiple instances of the same hook type
Hooks registered at different levels (global, client, invocation)
The specification explicitly states that hook data is not shared between different hooks, ensuring separation of concerns.
Integration with hook context
Hook data must be accessible through the hook context parameter passed to all hook stages. The typical pattern follows:
context.hookData.set("key", value) // In before stage
value = context.hookData.get("key") // In after stage
Learning from the .NET SDK implementation
The .NET SDK's PR open-feature/dotnet-sdk#387 provides implementation insights. Their approach enhanced the existing HookContext<T> class with a Data property, maintaining backward compatibility while adding new functionality. Lessons include:
API Design: The implementation uses a simple key-value store pattern that's intuitive for developers. Type safety is handled through casting when retrieving values, following .NET conventions.
No Breaking Changes: Existing hooks continue working without modification. The hook data feature is additive - hooks can opt-in to using it without requiring changes to hooks that don't need state sharing.
Examples: The implementation includes examples like timing hooks that measure execution duration, demonstrating the feature's value to developers.
Implementation roadmap for SDK maintainers
Phase 1: Core implementation
Start by implementing the basic hook data structure with these capabilities:
String-keyed storage with any-type values
Mutable data access through set/get operations
Proper lifecycle management (creation before first stage, cleanup after finally)
Thread-safe access for concurrent evaluations
Phase 2: Integration and testing
Integrate hook data with your existing hook infrastructure:
Add data property to hook context
Ensure data flows through all hook stages
Implement isolation between hook instances
Create comprehensive test suites covering edge cases
Phase 3: Documentation and examples
Provide guidance for hook developers:
API documentation with type signatures
Examples (timing, telemetry, validation)
Best practices and anti-patterns
Migration guide if introducing any changes
Implementation considerations
Memory management
Hook data should be garbage collected after the evaluation completes. Consider implementing weak references or explicit cleanup to prevent memory leaks in long-running applications.
Thread safety
Many applications evaluate flags concurrently. Ensure hook data access is thread-safe without introducing significant performance overhead. Consider using concurrent data structures appropriate for your language.
Type safety
In statically-typed languages, consider providing type-safe access patterns while maintaining the flexibility of arbitrary value storage. Generic methods or type assertions can help balance safety with usability.
Performance impact
Hook data should add minimal overhead to flag evaluations. Consider lazy initialization - only create the data structure when a hook actually uses it. Benchmark the implementation to ensure acceptable performance.
Common use cases to support
OpenTelemetry integration
The canonical use case involves creating spans in the before stage and ending them in after:
// Before stageSpanspan = tracer.spanBuilder("feature-flag-evaluation").startSpan();
context.hookData.set("span", span);
// After stageSpanspan = (Span) context.hookData.get("span");
span.end();
Performance monitoring
Tracking evaluation duration is a common requirement:
// Before stagecontext.Data.Set("startTime",DateTime.UtcNow);// After stagevarduration=DateTime.UtcNow-(DateTime)context.Data.Get("startTime");logger.LogInformation($"Evaluation took {duration.TotalMilliseconds}ms");
Multi-stage validation
Complex validation scenarios benefit from accumulating results:
Performance: Minimal overhead for evaluations not using hook data
Migration and compatibility
When implementing hook data support:
Maintain backward compatibility: Existing hooks must continue working
Version appropriately: Follow semantic versioning based on impact
Provide migration guides: Help developers adopt the new feature
Consider feature flags: Allow gradual rollout of hook data support
Success criteria
A complete hook data implementation should:
Pass all specification compliance tests
Support the primary use cases (telemetry, monitoring, validation)
Add minimal performance overhead
Provide good developer experience
Include comprehensive documentation
Maintain backward compatibility
Conclusion
Hook data provides a feature that enables observability and monitoring capabilities in OpenFeature. By following the specification requirements and learning from successful implementations like the .NET SDK, maintainers can provide consistent, reliable hook data support across all OpenFeature SDKs. The implementation should balance flexibility with safety, performance with functionality, and maintain the isolation guarantees that make hook data predictable and useful.
Summary
The OpenFeature specification now includes support for hook data, which allows hooks to maintain state across their execution stages (before → after/error → finally). This feature enables use cases like distributed tracing, performance monitoring, and multi-stage validation.
This issue tracks the implementation of hook data support in this SDK to achieve compliance with the latest specification.
Action Required
SDK maintainers need to implement hook data support according to the specification defined in:
A reference implementation is available in the .NET SDK PR: open-feature/dotnet-sdk#387
Hook data specification enables stateful hook operations
The OpenFeature hook data specification provides a mechanism for different stages of the same hook to share state during a single flag evaluation. This feature supports implementing telemetry, performance monitoring, and resource management use cases. The .NET SDK's implementation in open-feature/dotnet-sdk#387 demonstrates a successful approach that other SDKs can follow.
Reference Links
Understanding hook data fundamentals
Hook data provides the ability for hooks to maintain state across their execution lifecycle. When a hook starts an operation in the
before
stage (like opening a telemetry span), it needs a way to access that same data in theafter
stage to complete the operation. Without hook data, developers resort to workarounds like global state, weak maps, or thread-local storage, which introduce complexity and potential bugs.The specification defines hook data as a mutable, per-hook, per-evaluation data structure. This scoping means each hook instance gets its own isolated data store that persists only for the duration of a single flag evaluation. Different hooks evaluating the same flag don't share data, preventing interference and ensuring predictable behavior.
Core specification requirements
Data structure and access patterns
Hook data MUST be implemented as a structure supporting arbitrary properties with string keys and values of any type. The structure must be mutable to allow stages to modify shared state. SDKs typically implement this as a map-like interface with
set(key, value)
andget(key)
methods.The data structure must be created before the first hook stage executes and remain available throughout all stages (before → after/error → finally). This lifecycle management is the SDK's responsibility, not the hook developer's.
Isolation and scoping guarantees
Each hook instance maintains its own hook data - there's no sharing between different hooks. This isolation extends to:
The specification explicitly states that hook data is not shared between different hooks, ensuring separation of concerns.
Integration with hook context
Hook data must be accessible through the hook context parameter passed to all hook stages. The typical pattern follows:
Learning from the .NET SDK implementation
The .NET SDK's PR open-feature/dotnet-sdk#387 provides implementation insights. Their approach enhanced the existing
HookContext<T>
class with aData
property, maintaining backward compatibility while adding new functionality. Lessons include:API Design: The implementation uses a simple key-value store pattern that's intuitive for developers. Type safety is handled through casting when retrieving values, following .NET conventions.
No Breaking Changes: Existing hooks continue working without modification. The hook data feature is additive - hooks can opt-in to using it without requiring changes to hooks that don't need state sharing.
Examples: The implementation includes examples like timing hooks that measure execution duration, demonstrating the feature's value to developers.
Implementation roadmap for SDK maintainers
Phase 1: Core implementation
Start by implementing the basic hook data structure with these capabilities:
Phase 2: Integration and testing
Integrate hook data with your existing hook infrastructure:
Phase 3: Documentation and examples
Provide guidance for hook developers:
Implementation considerations
Memory management
Hook data should be garbage collected after the evaluation completes. Consider implementing weak references or explicit cleanup to prevent memory leaks in long-running applications.
Thread safety
Many applications evaluate flags concurrently. Ensure hook data access is thread-safe without introducing significant performance overhead. Consider using concurrent data structures appropriate for your language.
Type safety
In statically-typed languages, consider providing type-safe access patterns while maintaining the flexibility of arbitrary value storage. Generic methods or type assertions can help balance safety with usability.
Performance impact
Hook data should add minimal overhead to flag evaluations. Consider lazy initialization - only create the data structure when a hook actually uses it. Benchmark the implementation to ensure acceptable performance.
Common use cases to support
OpenTelemetry integration
The canonical use case involves creating spans in the
before
stage and ending them inafter
:Performance monitoring
Tracking evaluation duration is a common requirement:
Multi-stage validation
Complex validation scenarios benefit from accumulating results:
Testing requirements
Comprehensive test coverage should include:
Migration and compatibility
When implementing hook data support:
Success criteria
A complete hook data implementation should:
Conclusion
Hook data provides a feature that enables observability and monitoring capabilities in OpenFeature. By following the specification requirements and learning from successful implementations like the .NET SDK, maintainers can provide consistent, reliable hook data support across all OpenFeature SDKs. The implementation should balance flexibility with safety, performance with functionality, and maintain the isolation guarantees that make hook data predictable and useful.
Additional Resources
The text was updated successfully, but these errors were encountered: