refactor: bind providers explicitly to a registry with attach/detach (#324)
* test: make sure provider is registered in events test Signed-off-by: Federico Bond <federicobond@gmail.com> * refactor: bind providers explicitly to a registry with attach/detach Signed-off-by: Federico Bond <federicobond@gmail.com> --------- Signed-off-by: Federico Bond <federicobond@gmail.com>
This commit is contained in:
parent
f352045055
commit
c3ad697a80
|
|
@ -23,6 +23,15 @@ class ProviderStatus(Enum):
|
|||
|
||||
|
||||
class FeatureProvider(typing.Protocol): # pragma: no cover
|
||||
def attach(
|
||||
self,
|
||||
on_emit: typing.Callable[
|
||||
[FeatureProvider, ProviderEvent, ProviderEventDetails], None
|
||||
],
|
||||
) -> None: ...
|
||||
|
||||
def detach(self) -> None: ...
|
||||
|
||||
def initialize(self, evaluation_context: EvaluationContext) -> None: ...
|
||||
|
||||
def shutdown(self) -> None: ...
|
||||
|
|
@ -68,6 +77,18 @@ class FeatureProvider(typing.Protocol): # pragma: no cover
|
|||
|
||||
|
||||
class AbstractProvider(FeatureProvider):
|
||||
def attach(
|
||||
self,
|
||||
on_emit: typing.Callable[
|
||||
[FeatureProvider, ProviderEvent, ProviderEventDetails], None
|
||||
],
|
||||
) -> None:
|
||||
self._on_emit = on_emit
|
||||
|
||||
def detach(self) -> None:
|
||||
if hasattr(self, "_on_emit"):
|
||||
del self._on_emit
|
||||
|
||||
def initialize(self, evaluation_context: EvaluationContext) -> None:
|
||||
pass
|
||||
|
||||
|
|
@ -141,6 +162,5 @@ class AbstractProvider(FeatureProvider):
|
|||
self.emit(ProviderEvent.PROVIDER_STALE, details)
|
||||
|
||||
def emit(self, event: ProviderEvent, details: ProviderEventDetails) -> None:
|
||||
from openfeature.provider._registry import provider_registry
|
||||
|
||||
provider_registry.dispatch_event(self, event, details)
|
||||
if hasattr(self, "_on_emit"):
|
||||
self._on_emit(self, event, details)
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ class ProviderRegistry:
|
|||
return get_evaluation_context()
|
||||
|
||||
def _initialize_provider(self, provider: FeatureProvider) -> None:
|
||||
provider.attach(self.dispatch_event)
|
||||
try:
|
||||
if hasattr(provider, "initialize"):
|
||||
provider.initialize(self._get_evaluation_context())
|
||||
|
|
@ -106,6 +107,7 @@ class ProviderRegistry:
|
|||
error_code=ErrorCode.PROVIDER_FATAL,
|
||||
),
|
||||
)
|
||||
provider.detach()
|
||||
|
||||
def get_provider_status(self, provider: FeatureProvider) -> ProviderStatus:
|
||||
return self._provider_status.get(provider, ProviderStatus.NOT_READY)
|
||||
|
|
|
|||
|
|
@ -235,6 +235,8 @@ def test_clear_providers_shutdowns_every_provider_and_resets_default_provider():
|
|||
def test_provider_events():
|
||||
# Given
|
||||
spy = MagicMock()
|
||||
provider = NoOpProvider()
|
||||
set_provider(provider)
|
||||
|
||||
add_handler(ProviderEvent.PROVIDER_READY, spy.provider_ready)
|
||||
add_handler(
|
||||
|
|
@ -243,8 +245,6 @@ def test_provider_events():
|
|||
add_handler(ProviderEvent.PROVIDER_ERROR, spy.provider_error)
|
||||
add_handler(ProviderEvent.PROVIDER_STALE, spy.provider_stale)
|
||||
|
||||
provider = NoOpProvider()
|
||||
|
||||
provider_details = ProviderEventDetails(message="message")
|
||||
details = EventDetails.from_provider_event_details(
|
||||
provider.get_metadata().name, provider_details
|
||||
|
|
|
|||
Loading…
Reference in New Issue