-
Notifications
You must be signed in to change notification settings - Fork 25
feat(flagd-rpc): adding grace attempts #117
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
Changes from 5 commits
51d7651
07452ea
d15f529
c74d6ad
518572a
375c9c1
8f013d7
38cf9b9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| +0 −2 | .github/workflows/release-please.yml | |
| +1 −1 | .release-please-manifest.json | |
| +21 −0 | CHANGELOG.md | |
| +145 −85 | gherkin/config.feature | |
| +24 −0 | gherkin/events.feature |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -37,30 +37,32 @@ | |
|
|
||
|
|
||
| class GrpcResolver: | ||
| MAX_BACK_OFF = 120 | ||
|
|
||
| def __init__( | ||
| self, | ||
| config: Config, | ||
| emit_provider_ready: typing.Callable[[ProviderEventDetails], None], | ||
| emit_provider_error: typing.Callable[[ProviderEventDetails], None], | ||
| emit_provider_stale: typing.Callable[[ProviderEventDetails], None], | ||
| emit_provider_configuration_changed: typing.Callable[ | ||
| [ProviderEventDetails], None | ||
| ], | ||
| ): | ||
| self.config = config | ||
| self.emit_provider_ready = emit_provider_ready | ||
| self.emit_provider_error = emit_provider_error | ||
| self.emit_provider_stale = emit_provider_stale | ||
| self.emit_provider_configuration_changed = emit_provider_configuration_changed | ||
| self.cache: typing.Optional[BaseCacheImpl] = ( | ||
| LRUCache(maxsize=self.config.max_cache_size) | ||
| if self.config.cache_type == CacheType.LRU | ||
| if self.config.cache == CacheType.LRU | ||
| else None | ||
| ) | ||
| self.stub, self.channel = self._create_stub() | ||
| self.retry_backoff_seconds = config.retry_backoff_ms * 0.001 | ||
| self.retry_backoff_max_seconds = config.retry_backoff_ms * 0.001 | ||
aepfli marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| self.retry_grace_attempts = config.retry_grace_attempts | ||
| self.streamline_deadline_seconds = config.stream_deadline_ms * 0.001 | ||
| self.deadline = config.deadline * 0.001 | ||
| self.deadline = config.deadline_ms * 0.001 | ||
| self.connected = False | ||
|
|
||
| def _create_stub( | ||
|
|
@@ -70,13 +72,10 @@ def _create_stub( | |
| channel_factory = grpc.secure_channel if config.tls else grpc.insecure_channel | ||
| channel = channel_factory( | ||
| f"{config.host}:{config.port}", | ||
| options=(("grpc.keepalive_time_ms", config.keep_alive),), | ||
| options=(("grpc.keepalive_time_ms", config.keep_alive_time),), | ||
| ) | ||
| stub = evaluation_pb2_grpc.ServiceStub(channel) | ||
|
|
||
| if self.cache: | ||
| self.cache.clear() | ||
|
|
||
| return stub, channel | ||
|
|
||
| def initialize(self, evaluation_context: EvaluationContext) -> None: | ||
|
|
@@ -113,8 +112,10 @@ def listen(self) -> None: | |
| if self.streamline_deadline_seconds > 0 | ||
| else {} | ||
| ) | ||
| retry_counter = 0 | ||
| while self.active: | ||
| request = evaluation_pb2.EventStreamRequest() | ||
|
|
||
| try: | ||
| logger.debug("Setting up gRPC sync flags connection") | ||
| for message in self.stub.EventStream(request, **call_args): | ||
|
|
@@ -126,6 +127,7 @@ def listen(self) -> None: | |
| ) | ||
| ) | ||
| self.connected = True | ||
| retry_counter = 0 | ||
| # reset retry delay after successsful read | ||
| retry_delay = self.retry_backoff_seconds | ||
|
|
||
|
|
@@ -146,15 +148,37 @@ def listen(self) -> None: | |
| ) | ||
|
|
||
| self.connected = False | ||
| self.handle_error(retry_counter, retry_delay) | ||
|
|
||
| retry_delay = self.handle_retry(retry_counter, retry_delay) | ||
|
|
||
| retry_counter = retry_counter + 1 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just for my understanding. The
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are right.
|
||
|
|
||
| def handle_retry(self, retry_counter: int, retry_delay: float) -> float: | ||
| if retry_counter == 0: | ||
| logger.info("gRPC sync disconnected, reconnecting immediately") | ||
| else: | ||
| logger.info(f"gRPC sync disconnected, reconnecting in {retry_delay}s") | ||
| time.sleep(retry_delay) | ||
| retry_delay = min(1.1 * retry_delay, self.retry_backoff_max_seconds) | ||
| return retry_delay | ||
|
|
||
| def handle_error(self, retry_counter: int, retry_delay: float) -> None: | ||
| if retry_counter == self.retry_grace_attempts: | ||
| if self.cache: | ||
| self.cache.clear() | ||
| self.emit_provider_error( | ||
| ProviderEventDetails( | ||
| message=f"gRPC sync disconnected, reconnecting in {retry_delay}s", | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't we increase
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We increment the |
||
| error_code=ErrorCode.GENERAL, | ||
| ) | ||
| ) | ||
| logger.info(f"gRPC sync disconnected, reconnecting in {retry_delay}s") | ||
| time.sleep(retry_delay) | ||
| retry_delay = min(1.1 * retry_delay, self.MAX_BACK_OFF) | ||
| elif retry_counter == 1: | ||
| self.emit_provider_stale( | ||
| ProviderEventDetails( | ||
| message=f"gRPC sync disconnected, reconnecting in {retry_delay}s", | ||
| ) | ||
| ) | ||
|
|
||
| def handle_changed_flags(self, data: typing.Any) -> None: | ||
| changed_flags = list(data["flags"].keys()) | ||
|
|
||
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 added this to be compliant with the config gherkin test - usage of this will be fixed as soon as we touch the in-process provider