Skip to content

Commit cef19ac

Browse files
committed
[ffe] integrate datadog-ffe
1 parent 13e4d43 commit cef19ac

File tree

9 files changed

+896
-91
lines changed

9 files changed

+896
-91
lines changed

ddtrace/internal/native/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from ._native import SerializationError # noqa: F401
1616
from ._native import TraceExporter # noqa: F401
1717
from ._native import TraceExporterBuilder # noqa: F401
18-
from ._native import ffande_process_config # noqa: F401
18+
from ._native import ffe # noqa: F401
1919
from ._native import logger # noqa: F401
2020
from ._native import store_metadata # noqa: F401
2121

ddtrace/internal/native/_native.pyi

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
from typing import Dict, List, Literal, Optional
1+
from typing import Dict, List, Literal, Optional, Any
2+
from enum import Enum
23

34
class DDSketch:
45
def __init__(self): ...
@@ -447,11 +448,56 @@ class SerializationError(Exception):
447448

448449
...
449450

450-
def ffande_process_config(config_bytes: bytes) -> Optional[bool]:
451+
class ffe:
451452
"""
452-
Process feature flagging and experimentation configuration rules.
453-
454-
:param config_bytes: Raw bytes containing the configuration data
455-
:return: True if processing was successful, False otherwise, None on error
453+
Native Feature Flags and Experimentation module.
456454
"""
457-
...
455+
456+
class FlagType(Enum):
457+
String = ...
458+
Integer = ...
459+
Float = ...
460+
Boolean = ...
461+
Object = ...
462+
463+
class Reason(Enum):
464+
Static = ...
465+
Default = ...
466+
TargetingMatch = ...
467+
Split = ...
468+
Cached = ...
469+
Disabled = ...
470+
Unknown = ...
471+
Stale = ...
472+
Error = ...
473+
474+
class ErrorCode(Enum):
475+
TypeMismatch = ...
476+
ParseError = ...
477+
FlagNotFound = ...
478+
TargetingKeyMissing = ...
479+
InvalidContext = ...
480+
ProviderNotReady = ...
481+
General = ...
482+
483+
class ResolutionDetails:
484+
@property
485+
def value() -> Optional[Any]: ...
486+
@property
487+
def error_code() -> Optional[ffe.ErrorCode]: ...
488+
@property
489+
def error_message() -> Optional[str]: ...
490+
@property
491+
def reason() -> Optional[ffe.Reason]: ...
492+
@property
493+
def variant() -> Optional[str]: ...
494+
@property
495+
def flag_metadata() -> dict[str, str]: ...
496+
@property
497+
def do_log() -> bool: ...
498+
@property
499+
def extra_logging() -> Optional[dict[str, str]]: ...
500+
501+
class Configuration:
502+
def __init__(config_bytes: bytes) -> None: ...
503+
def resolve_value(self, flag_key: str, expected_type: ffe.FlagType, context: dict) -> ffe.ResolutionDetails: ...
Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
"""
2-
Native interface for FFAndE (Feature Flagging and Experimentation) processing.
2+
Native interface for FFE (Feature Flagging and Experimentation) processing.
33
44
This module provides the interface to the PyO3 native function that processes
55
feature flag configuration rules.
66
"""
7+
78
from typing import Optional
89

910
from ddtrace.internal.logger import get_logger
@@ -14,19 +15,13 @@
1415
is_available = True
1516

1617
try:
17-
from ddtrace.internal.native._native import ffande_process_config
18+
from ddtrace.internal.native._native import ffe
1819
except ImportError:
1920
is_available = False
20-
log.debug("FFAndE native module not available, feature flag processing disabled")
21-
22-
# Provide a no-op fallback
23-
def ffande_process_config(config_bytes: bytes) -> Optional[bool]:
24-
"""Fallback implementation when native module is not available."""
25-
log.warning("FFAndE native module not available, ignoring configuration")
26-
return None
21+
log.debug("FFE native module not available, feature flag processing disabled")
2722

2823

29-
def process_ffe_configuration(config_bytes: bytes) -> bool:
24+
def process_ffe_configuration(config_bytes: bytes) -> Optional[ffe.Configuration]:
3025
"""
3126
Process feature flag configuration by forwarding raw bytes to native function.
3227
@@ -37,15 +32,11 @@ def process_ffe_configuration(config_bytes: bytes) -> bool:
3732
True if processing was successful, False otherwise
3833
"""
3934
if not is_available:
40-
log.debug("FFAndE native module not available, skipping configuration")
35+
log.debug("FFE native module not available, skipping configuration")
4136
return False
4237

4338
try:
44-
result = ffande_process_config(config_bytes)
45-
if result is None:
46-
log.debug("FFAndE native processing returned None")
47-
return False
48-
return result
39+
return ffe.Configuration(config_bytes)
4940
except Exception as e:
5041
log.error("Error processing FFE configuration: %s", e, exc_info=True)
51-
return False
42+
return None

0 commit comments

Comments
 (0)