-
Notifications
You must be signed in to change notification settings - Fork 35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Add blocking timeout in polling manager #211
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice pick threading.condition. Please address comments and add unit tests.
optimizely/config_manager.py
Outdated
@@ -145,6 +146,9 @@ def get_config(self): | |||
Returns: | |||
ProjectConfig. None if not set. | |||
""" | |||
self._condition.acquire() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should only be doing this for the first time. See Ruby.
optimizely/config_manager.py
Outdated
self.last_modified = None | ||
self._polling_thread = threading.Thread(target=self._run) | ||
self._polling_thread.setDaemon(True) | ||
self._polling_thread.start() | ||
self._condition = threading.Condition() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You will have to put this inside static config manager since you use it in it's method.
optimizely/config_manager.py
Outdated
Args: | ||
blocking_timeout: Time in seconds to block the config call. | ||
""" | ||
if not blocking_timeout: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit. Check if it's None. Otherwise, this will be true when blocking_timeout is 0
optimizely/config_manager.py
Outdated
""" | ||
if not blocking_timeout: | ||
blocking_timeout = enums.ConfigManager.DEFAULT_BLOCKING_TIMEOUT | ||
self.logger.debug('Set config blocking timeout to default value {}.'.format(blocking_timeout)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit. See log in Ruby
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit. Setting
optimizely/config_manager.py
Outdated
blocking_timeout = enums.ConfigManager.DEFAULT_BLOCKING_TIMEOUT | ||
self.logger.debug('Set config blocking timeout to default value {}.'.format(blocking_timeout)) | ||
|
||
if not isinstance(blocking_timeout, (int, float)): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use numbers.Integral instead of int. This will cover long for Python 2 as well
optimizely/config_manager.py
Outdated
) | ||
|
||
# If blocking timeout is less than or equal to 0 then set it to default blocking timeout. | ||
if blocking_timeout <= 0: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why haven't you enforced MIN and MAX limit as in Ruby SDK?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel 0 should be allowed as a value if people are not interested in blocking.
@rashidsp Use threading.Event instead. https://docs.python.org/2.7/library/threading.html?highlight=condition%20acquire#event-objects |
1 similar comment
optimizely/config_manager.py
Outdated
@@ -95,6 +96,7 @@ def __init__(self, | |||
notification_center=notification_center) | |||
self._config = None | |||
self.validate_schema = not skip_json_validation | |||
self._configReadyEvent = threading.Event() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this camelCased when (almost) the entirety of this SDK is snake cased?
optimizely/config_manager.py
Outdated
""" | ||
if not blocking_timeout: | ||
blocking_timeout = enums.ConfigManager.DEFAULT_BLOCKING_TIMEOUT | ||
self.logger.debug('Set config blocking timeout to default value {}.'.format(blocking_timeout)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit. Setting
optimizely/config_manager.py
Outdated
) | ||
|
||
# If blocking timeout is less than or equal to 0 then set it to default blocking timeout. | ||
if blocking_timeout <= 0: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel 0 should be allowed as a value if people are not interested in blocking.
optimizely/config_manager.py
Outdated
@@ -133,6 +135,7 @@ def _set_config(self, datafile): | |||
return | |||
|
|||
self._config = config | |||
self._configReadyEvent.set() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the effect of calling set()
twice
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No effect. It will make the already 'true' internal flag to 'true' again. Once an event has been set, all the threads which wait for the events do not block until .clear() has been called on the event, which makes the internal flag false.
optimizely/helpers/enums.py
Outdated
@@ -38,6 +38,8 @@ class AudienceEvaluationLogs(object): | |||
|
|||
class ConfigManager(object): | |||
DATAFILE_URL_TEMPLATE = 'https://cdn.optimizely.com/datafiles/{sdk_key}.json' | |||
# Default time in seconds to block the 'get_config' method call until 'config' instance has been initialized. | |||
DEFAULT_BLOCKING_TIMEOUT = 15 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's make this 10 seconds.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Summary
This introduces blocking timeout in Python Config Manager. Config Manager will block the main thread until the config is available or the timeout occurs.
https://github.com/optimizely/python-testapp/pull/63 should be merged to pass FSC tests for this PR.