Skip to content

Commit 84af1ae

Browse files
feat: implement initialize/shutdown on provider registration (#213)
Signed-off-by: Federico Bond <[email protected]> Co-authored-by: Michael Beemer <[email protected]>
1 parent 88a204d commit 84af1ae

File tree

3 files changed

+53
-0
lines changed

3 files changed

+53
-0
lines changed

openfeature/api.py

+7
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ def set_provider(provider: AbstractProvider):
2525
global _provider
2626
if provider is None:
2727
raise GeneralError(error_message="No provider")
28+
if _provider:
29+
_provider.shutdown()
2830
_provider = provider
31+
provider.initialize(_evaluation_context)
2932

3033

3134
def get_provider() -> typing.Optional[AbstractProvider]:
@@ -63,3 +66,7 @@ def clear_hooks():
6366
def get_hooks() -> typing.List[Hook]:
6467
global _hooks
6568
return _hooks
69+
70+
71+
def shutdown():
72+
_provider.shutdown()

openfeature/provider/provider.py

+6
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@
88

99

1010
class AbstractProvider:
11+
def initialize(self, evaluation_context: EvaluationContext):
12+
pass
13+
14+
def shutdown(self):
15+
pass
16+
1117
@abstractmethod
1218
def get_metadata(self) -> Metadata:
1319
pass

tests/test_api.py

+40
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@
1212
get_provider_metadata,
1313
set_evaluation_context,
1414
set_provider,
15+
shutdown,
1516
)
1617
from openfeature.evaluation_context import EvaluationContext
1718
from openfeature.exception import ErrorCode, GeneralError
1819
from openfeature.hook import Hook
1920
from openfeature.provider.metadata import Metadata
2021
from openfeature.provider.no_op_provider import NoOpProvider
22+
from openfeature.provider.provider import AbstractProvider
2123

2224

2325
def test_should_not_raise_exception_with_noop_client():
@@ -56,6 +58,32 @@ def test_should_try_set_provider_and_fail_if_none_provided():
5658
assert ge.value.error_code == ErrorCode.GENERAL
5759

5860

61+
def test_should_invoke_provider_initialize_function_on_newly_registered_provider():
62+
# Given
63+
evaluation_context = EvaluationContext("targeting_key", {"attr1": "val1"})
64+
provider = MagicMock(spec=AbstractProvider)
65+
66+
# When
67+
set_evaluation_context(evaluation_context)
68+
set_provider(provider)
69+
70+
# Then
71+
provider.initialize.assert_called_with(evaluation_context)
72+
73+
74+
def test_should_invoke_provider_shutdown_function_once_provider_is_no_longer_in_use():
75+
# Given
76+
provider_1 = MagicMock(spec=AbstractProvider)
77+
provider_2 = MagicMock(spec=AbstractProvider)
78+
79+
# When
80+
set_provider(provider_1)
81+
set_provider(provider_2)
82+
83+
# Then
84+
assert provider_1.shutdown.called
85+
86+
5987
def test_should_return_a_provider_if_setup_correctly():
6088
# Given
6189
set_provider(NoOpProvider())
@@ -116,3 +144,15 @@ def test_should_add_hooks_to_api_hooks():
116144

117145
# Then
118146
assert get_hooks() == [hook_1, hook_2]
147+
148+
149+
def test_should_call_provider_shutdown_on_api_shutdown():
150+
# Given
151+
provider = MagicMock(spec=AbstractProvider)
152+
set_provider(provider)
153+
154+
# When
155+
shutdown()
156+
157+
# Then
158+
assert provider.shutdown.called

0 commit comments

Comments
 (0)