From 87c56c94784ba3ccccd0a2001becbf0dd4e71e30 Mon Sep 17 00:00:00 2001 From: "Matthew M. Keeler" Date: Thu, 25 Jul 2024 14:28:04 -0400 Subject: [PATCH] feat: Add option to enable event payload compression (#300) --- contract-tests/client_entity.py | 1 + contract-tests/service.py | 2 ++ ldclient/config.py | 9 ++++++++- ldclient/impl/events/event_processor.py | 7 ++++++- 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/contract-tests/client_entity.py b/contract-tests/client_entity.py index bc119fc..4b5a717 100644 --- a/contract-tests/client_entity.py +++ b/contract-tests/client_entity.py @@ -41,6 +41,7 @@ def __init__(self, tag, config): if config.get("events") is not None: events = config["events"] + opts["enable_event_compression"] = events.get("enableGzip", False) if events.get("baseUri") is not None: opts["events_uri"] = events["baseUri"] if events.get("capacity") is not None: diff --git a/contract-tests/service.py b/contract-tests/service.py index 1fa9a97..1a069b7 100644 --- a/contract-tests/service.py +++ b/contract-tests/service.py @@ -70,6 +70,8 @@ def status(): 'secure-mode-hash', 'tags', 'migrations', + 'event-gzip', + 'optional-event-gzip', 'event-sampling', 'polling-gzip', 'inline-context', diff --git a/ldclient/config.py b/ldclient/config.py index 12539ce..0c06e1d 100644 --- a/ldclient/config.py +++ b/ldclient/config.py @@ -175,7 +175,8 @@ def __init__(self, http: HTTPConfig=HTTPConfig(), big_segments: Optional[BigSegmentsConfig]=None, application: Optional[dict]=None, - hooks: Optional[List[Hook]]=None): + hooks: Optional[List[Hook]]=None, + enable_event_compression: bool=False): """ :param sdk_key: The SDK key for your LaunchDarkly account. This is always required. :param base_uri: The base URL for the LaunchDarkly server. Most users should use the default @@ -241,6 +242,7 @@ def __init__(self, :class:`HTTPConfig`. :param application: Optional properties for setting application metadata. See :py:attr:`~application` :param hooks: Hooks provide entrypoints which allow for observation of SDK functions. + :param enable_event_compression: Whether or not to enable GZIP compression for outgoing events. """ self.__sdk_key = sdk_key @@ -274,6 +276,7 @@ def __init__(self, self.__big_segments = BigSegmentsConfig() if not big_segments else big_segments self.__application = validate_application_info(application or {}, log) self.__hooks = [hook for hook in hooks if isinstance(hook, Hook)] if hooks else [] + self.__enable_event_compression = enable_event_compression self._data_source_update_sink: Optional[DataSourceUpdateSink] = None def copy_with_new_sdk_key(self, new_sdk_key: str) -> 'Config': @@ -459,6 +462,10 @@ def hooks(self) -> List[Hook]: """ return self.__hooks + @property + def enable_event_compression(self) -> bool: + return self.__enable_event_compression + @property def data_source_update_sink(self) -> Optional[DataSourceUpdateSink]: """ diff --git a/ldclient/impl/events/event_processor.py b/ldclient/impl/events/event_processor.py index b86b74b..7549027 100644 --- a/ldclient/impl/events/event_processor.py +++ b/ldclient/impl/events/event_processor.py @@ -12,6 +12,7 @@ import uuid import queue import urllib3 +import gzip from ldclient.config import Config from datetime import timedelta from random import Random @@ -559,11 +560,15 @@ def _post_events_with_retry( ): hdrs = _headers(config) hdrs['Content-Type'] = 'application/json' + if config.enable_event_compression: + hdrs['Content-Encoding'] = 'gzip' + if payload_id: hdrs['X-LaunchDarkly-Event-Schema'] = str(__CURRENT_EVENT_SCHEMA__) hdrs['X-LaunchDarkly-Payload-ID'] = payload_id can_retry = True context = "posting %s" % events_description + data = gzip.compress(bytes(body, 'utf-8')) if config.enable_event_compression else body while True: next_action_message = "will retry" if can_retry else "some events were dropped" try: @@ -571,7 +576,7 @@ def _post_events_with_retry( 'POST', uri, headers=hdrs, - body=body, + body=data, timeout=urllib3.Timeout(connect=config.http.connect_timeout, read=config.http.read_timeout), retries=0 )