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
|
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 initialize(self, evaluation_context: EvaluationContext) -> None: ...
|
||||||
|
|
||||||
def shutdown(self) -> None: ...
|
def shutdown(self) -> None: ...
|
||||||
|
|
@ -68,6 +77,18 @@ class FeatureProvider(typing.Protocol): # pragma: no cover
|
||||||
|
|
||||||
|
|
||||||
class AbstractProvider(FeatureProvider):
|
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:
|
def initialize(self, evaluation_context: EvaluationContext) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
@ -141,6 +162,5 @@ class AbstractProvider(FeatureProvider):
|
||||||
self.emit(ProviderEvent.PROVIDER_STALE, details)
|
self.emit(ProviderEvent.PROVIDER_STALE, details)
|
||||||
|
|
||||||
def emit(self, event: ProviderEvent, details: ProviderEventDetails) -> None:
|
def emit(self, event: ProviderEvent, details: ProviderEventDetails) -> None:
|
||||||
from openfeature.provider._registry import provider_registry
|
if hasattr(self, "_on_emit"):
|
||||||
|
self._on_emit(self, event, details)
|
||||||
provider_registry.dispatch_event(self, event, details)
|
|
||||||
|
|
|
||||||
|
|
@ -71,6 +71,7 @@ class ProviderRegistry:
|
||||||
return get_evaluation_context()
|
return get_evaluation_context()
|
||||||
|
|
||||||
def _initialize_provider(self, provider: FeatureProvider) -> None:
|
def _initialize_provider(self, provider: FeatureProvider) -> None:
|
||||||
|
provider.attach(self.dispatch_event)
|
||||||
try:
|
try:
|
||||||
if hasattr(provider, "initialize"):
|
if hasattr(provider, "initialize"):
|
||||||
provider.initialize(self._get_evaluation_context())
|
provider.initialize(self._get_evaluation_context())
|
||||||
|
|
@ -106,6 +107,7 @@ class ProviderRegistry:
|
||||||
error_code=ErrorCode.PROVIDER_FATAL,
|
error_code=ErrorCode.PROVIDER_FATAL,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
provider.detach()
|
||||||
|
|
||||||
def get_provider_status(self, provider: FeatureProvider) -> ProviderStatus:
|
def get_provider_status(self, provider: FeatureProvider) -> ProviderStatus:
|
||||||
return self._provider_status.get(provider, ProviderStatus.NOT_READY)
|
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():
|
def test_provider_events():
|
||||||
# Given
|
# Given
|
||||||
spy = MagicMock()
|
spy = MagicMock()
|
||||||
|
provider = NoOpProvider()
|
||||||
|
set_provider(provider)
|
||||||
|
|
||||||
add_handler(ProviderEvent.PROVIDER_READY, spy.provider_ready)
|
add_handler(ProviderEvent.PROVIDER_READY, spy.provider_ready)
|
||||||
add_handler(
|
add_handler(
|
||||||
|
|
@ -243,8 +245,6 @@ def test_provider_events():
|
||||||
add_handler(ProviderEvent.PROVIDER_ERROR, spy.provider_error)
|
add_handler(ProviderEvent.PROVIDER_ERROR, spy.provider_error)
|
||||||
add_handler(ProviderEvent.PROVIDER_STALE, spy.provider_stale)
|
add_handler(ProviderEvent.PROVIDER_STALE, spy.provider_stale)
|
||||||
|
|
||||||
provider = NoOpProvider()
|
|
||||||
|
|
||||||
provider_details = ProviderEventDetails(message="message")
|
provider_details = ProviderEventDetails(message="message")
|
||||||
details = EventDetails.from_provider_event_details(
|
details = EventDetails.from_provider_event_details(
|
||||||
provider.get_metadata().name, provider_details
|
provider.get_metadata().name, provider_details
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue