Skip to content

Commit e46df7e

Browse files
committed
fix: fix status handlers running immediately if provider already in associated state
Signed-off-by: Federico Bond <[email protected]>
1 parent bede671 commit e46df7e

File tree

4 files changed

+34
-9
lines changed

4 files changed

+34
-9
lines changed

openfeature/api.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ def set_provider(
3939

4040

4141
def clear_providers() -> None:
42-
return _provider_registry.clear_providers()
42+
_provider_registry.clear_providers()
43+
_event_support.clear()
4344

4445

4546
def get_provider_metadata(domain: typing.Optional[str] = None) -> Metadata:

openfeature/event.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from typing import TYPE_CHECKING, Callable, Dict, List, Optional, Union
77

88
from openfeature.exception import ErrorCode
9-
from openfeature.provider import FeatureProvider
9+
from openfeature.provider import FeatureProvider, ProviderStatus
1010

1111
if TYPE_CHECKING:
1212
from openfeature.client import OpenFeatureClient
@@ -16,9 +16,18 @@ class ProviderEvent(Enum):
1616
PROVIDER_READY = "PROVIDER_READY"
1717
PROVIDER_CONFIGURATION_CHANGED = "PROVIDER_CONFIGURATION_CHANGED"
1818
PROVIDER_ERROR = "PROVIDER_ERROR"
19+
PROVIDER_FATAL = "PROVIDER_FATAL"
1920
PROVIDER_STALE = "PROVIDER_STALE"
2021

2122

23+
_provider_status_to_event = {
24+
ProviderStatus.READY: ProviderEvent.PROVIDER_READY,
25+
ProviderStatus.ERROR: ProviderEvent.PROVIDER_ERROR,
26+
ProviderStatus.FATAL: ProviderEvent.PROVIDER_FATAL,
27+
ProviderStatus.STALE: ProviderEvent.PROVIDER_STALE,
28+
}
29+
30+
2231
@dataclass
2332
class ProviderEventDetails:
2433
flags_changed: Optional[List[str]] = None
@@ -114,6 +123,9 @@ def run_handlers_for_provider(
114123
def _run_immediate_handler(
115124
self, client: OpenFeatureClient, event: ProviderEvent, handler: EventHandler
116125
) -> None:
117-
if event == ProviderEvent.PROVIDER_READY:
118-
# providers are assumed ready because provider status is not yet implemented
126+
if event == _provider_status_to_event.get(client.get_provider_status()):
119127
handler(EventDetails(provider_name=client.provider.get_metadata().name))
128+
129+
def clear(self) -> None:
130+
self._global_handlers.clear()
131+
self._client_handlers.clear()

openfeature/provider/registry.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import typing
22

33
from openfeature.evaluation_context import EvaluationContext
4+
from openfeature.event import (
5+
ProviderEventDetails,
6+
_provider_status_to_event,
7+
)
48
from openfeature.exception import ErrorCode, GeneralError, OpenFeatureError
59
from openfeature.provider import FeatureProvider, ProviderStatus
610
from openfeature.provider.no_op_provider import NoOpProvider
@@ -14,8 +18,9 @@ class ProviderRegistry:
1418
def __init__(self) -> None:
1519
self._default_provider = NoOpProvider()
1620
self._providers = {}
17-
self._provider_status = {}
18-
self._set_provider_status(self._default_provider, ProviderStatus.NOT_READY)
21+
self._provider_status = {
22+
self._default_provider: ProviderStatus.READY,
23+
}
1924

2025
def set_provider(self, domain: str, provider: FeatureProvider) -> None:
2126
if provider is None:
@@ -50,6 +55,9 @@ def clear_providers(self) -> None:
5055
self.shutdown()
5156
self._providers.clear()
5257
self._default_provider = NoOpProvider()
58+
self._provider_status = {
59+
self._default_provider: ProviderStatus.READY,
60+
}
5361

5462
def shutdown(self) -> None:
5563
for provider in {self._default_provider, *self._providers.values()}:
@@ -90,3 +98,8 @@ def _set_provider_status(
9098
self, provider: FeatureProvider, status: ProviderStatus
9199
) -> None:
92100
self._provider_status[provider] = status
101+
102+
if event := _provider_status_to_event.get(status):
103+
from openfeature.api import _run_handlers_for_provider
104+
105+
_run_handlers_for_provider(provider, event, ProviderEventDetails())

tests/conftest.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,12 @@
55

66

77
@pytest.fixture(autouse=True)
8-
def clear_provider():
8+
def clear_providers():
99
"""
1010
For tests that use set_provider(), we need to clear the provider to avoid issues
1111
in other tests.
1212
"""
13-
yield
14-
_provider = None
13+
api.clear_providers()
1514

1615

1716
@pytest.fixture()

0 commit comments

Comments
 (0)