chore(flagd): Add sync metadata disabled (#211)

* chore(flagd): add disable metadata option

Signed-off-by: Maks Osowski <maks@google.com>

* chore(flagd): Minimally refactor GrpcWatcher.listen() to pass ruff complexity pre-commit

Signed-off-by: Maks Osowski <maks@google.com>

* Update providers/openfeature-provider-flagd/src/openfeature/contrib/provider/flagd/config.py

Co-authored-by: Anton Grübel <anton.gruebel@gmail.com>
Signed-off-by: cupofcat <maks@google.com>

---------

Signed-off-by: Maks Osowski <maks@google.com>
Signed-off-by: cupofcat <maks@google.com>
Co-authored-by: Anton Grübel <anton.gruebel@gmail.com>
This commit is contained in:
cupofcat 2025-03-12 18:55:44 +01:00 committed by GitHub
parent 345e7934b9
commit 2f85057494
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 34 additions and 10 deletions

View File

@ -100,6 +100,7 @@ class Config:
cert_path: typing.Optional[str] = None,
default_authority: typing.Optional[str] = None,
channel_credentials: typing.Optional[grpc.ChannelCredentials] = None,
sync_metadata_disabled: typing.Optional[bool] = None,
):
self.host = env_or_default(ENV_VAR_HOST, DEFAULT_HOST) if host is None else host
@ -248,3 +249,11 @@ class Config:
)
self.channel_credentials = channel_credentials
# TODO: remove the metadata call entirely after https://github.com/open-feature/flagd/issues/1584
# This is a temporary stop-gap solutions to support servers that don't implement sync.GetMetadata
# (see: https://buf.build/open-feature/flagd/docs/main:flagd.sync.v1#flagd.sync.v1.FlagSyncService.GetMetadata).
# Using this option disables call to sync.GetMetadata
# Disabling will prevent static context from flagd being used in evaluations.
# GetMetadata and this option will be removed.
self.sync_metadata_disabled = sync_metadata_disabled

View File

@ -64,6 +64,7 @@ class FlagdProvider(AbstractProvider):
cert_path: typing.Optional[str] = None,
default_authority: typing.Optional[str] = None,
channel_credentials: typing.Optional[grpc.ChannelCredentials] = None,
sync_metadata_disabled: typing.Optional[bool] = None,
):
"""
Create an instance of the FlagdProvider
@ -106,6 +107,7 @@ class FlagdProvider(AbstractProvider):
cert_path=cert_path,
default_authority=default_authority,
channel_credentials=channel_credentials,
sync_metadata_disabled=sync_metadata_disabled,
)
self.enriched_context: dict = {}

View File

@ -6,6 +6,7 @@ import typing
import grpc
from google.protobuf.json_format import MessageToDict
from google.protobuf.struct_pb2 import Struct
from openfeature.evaluation_context import EvaluationContext
from openfeature.event import ProviderEventDetails
@ -162,24 +163,36 @@ class GrpcWatcher(FlagStateConnector):
self.active = False
self.channel.close()
def listen(self) -> None:
call_args = (
{"timeout": self.streamline_deadline_seconds}
if self.streamline_deadline_seconds > 0
else {}
)
def _create_request_args(self) -> dict:
request_args = {}
if self.selector is not None:
request_args["selector"] = self.selector
if self.provider_id is not None:
request_args["provider_id"] = self.provider_id
return request_args
def listen(self) -> None:
call_args = (
{"timeout": self.streamline_deadline_seconds}
if self.streamline_deadline_seconds > 0
else {}
)
request_args = self._create_request_args()
while self.active:
try:
context_values_request = sync_pb2.GetMetadataRequest()
context_values_response: sync_pb2.GetMetadataResponse = (
self.stub.GetMetadata(context_values_request, wait_for_ready=True)
)
context_values_response: sync_pb2.GetMetadataResponse
if self.config.sync_metadata_disabled:
context_values_response = sync_pb2.GetMetadataResponse(
metadata=Struct()
)
else:
context_values_request = sync_pb2.GetMetadataRequest()
context_values_response = self.stub.GetMetadata(
context_values_request, wait_for_ready=True
)
context_values = MessageToDict(context_values_response)
request = sync_pb2.SyncFlagsRequest(**request_args)