splitio-commons 1.0.0__tar.gz → 1.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/NOTICE.txt +1 -1
  2. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/PKG-INFO +4 -4
  3. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/setup.py +3 -3
  4. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/api/segments.py +7 -0
  5. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/push/sse.py +4 -2
  6. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/recorder/recorder.py +39 -6
  7. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/storage/inmemmory.py +23 -39
  8. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/sync/definition.py +4 -4
  9. splitio_commons-1.1.0/splitio_commons/version.py +1 -0
  10. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons.egg-info/PKG-INFO +4 -4
  11. splitio_commons-1.0.0/splitio_commons/version.py +0 -1
  12. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/LICENSE.txt +0 -0
  13. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/README.md +0 -0
  14. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/setup.cfg +0 -0
  15. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/__init__.py +0 -0
  16. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/api/__init__.py +0 -0
  17. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/api/auth.py +0 -0
  18. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/api/client.py +0 -0
  19. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/api/commons.py +0 -0
  20. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/api/definitions.py +0 -0
  21. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/api/events.py +0 -0
  22. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/api/impressions.py +0 -0
  23. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/api/telemetry.py +0 -0
  24. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/api/util.py +0 -0
  25. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/engine/__init__.py +0 -0
  26. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/engine/cache/__init__.py +0 -0
  27. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/engine/cache/lru.py +0 -0
  28. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/engine/evaluator.py +0 -0
  29. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/engine/filters.py +0 -0
  30. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/engine/hashfns/__init__.py +0 -0
  31. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/engine/hashfns/legacy.py +0 -0
  32. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/engine/hashfns/murmur3py.py +0 -0
  33. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/engine/impressions/__init__.py +0 -0
  34. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/engine/impressions/adapters.py +0 -0
  35. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/engine/impressions/impressions.py +0 -0
  36. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/engine/impressions/manager.py +0 -0
  37. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/engine/impressions/strategies.py +0 -0
  38. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/engine/impressions/unique_keys_tracker.py +0 -0
  39. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/engine/splitters.py +0 -0
  40. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/engine/telemetry.py +0 -0
  41. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/events/__init__.py +0 -0
  42. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/events/events_delivery.py +0 -0
  43. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/events/events_manager.py +0 -0
  44. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/events/events_manager_config.py +0 -0
  45. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/events/events_metadata.py +0 -0
  46. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/events/events_task.py +0 -0
  47. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/__init__.py +0 -0
  48. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/configs.py +0 -0
  49. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/datatypes.py +0 -0
  50. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/definitions.py +0 -0
  51. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/events.py +0 -0
  52. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/fallback_config.py +0 -0
  53. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/fallback_treatment.py +0 -0
  54. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/grammar/__init__.py +0 -0
  55. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/grammar/condition.py +0 -0
  56. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/grammar/matchers/__init__.py +0 -0
  57. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/grammar/matchers/base.py +0 -0
  58. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/grammar/matchers/keys.py +0 -0
  59. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/grammar/matchers/misc.py +0 -0
  60. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/grammar/matchers/numeric.py +0 -0
  61. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/grammar/matchers/prerequisites.py +0 -0
  62. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/grammar/matchers/rule_based_segment.py +0 -0
  63. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/grammar/matchers/semver.py +0 -0
  64. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/grammar/matchers/sets.py +0 -0
  65. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/grammar/matchers/string.py +0 -0
  66. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/grammar/matchers/utils/__init__.py +0 -0
  67. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/grammar/matchers/utils/utils.py +0 -0
  68. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/grammar/partitions.py +0 -0
  69. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/impressions.py +0 -0
  70. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/key.py +0 -0
  71. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/notification.py +0 -0
  72. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/rule_based_segments.py +0 -0
  73. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/segments.py +0 -0
  74. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/splits.py +0 -0
  75. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/telemetry.py +0 -0
  76. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/models/token.py +0 -0
  77. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/optional/__init__.py +0 -0
  78. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/optional/loaders.py +0 -0
  79. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/push/__init__.py +0 -0
  80. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/push/manager.py +0 -0
  81. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/push/parser.py +0 -0
  82. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/push/processor.py +0 -0
  83. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/push/splitsse.py +0 -0
  84. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/push/status_tracker.py +0 -0
  85. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/push/workers.py +0 -0
  86. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/recorder/__init__.py +0 -0
  87. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/storage/__init__.py +0 -0
  88. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/storage/adapters/__init__.py +0 -0
  89. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/storage/adapters/cache_trait.py +0 -0
  90. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/storage/adapters/redis.py +0 -0
  91. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/storage/adapters/util.py +0 -0
  92. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/storage/pluggable.py +0 -0
  93. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/storage/redis.py +0 -0
  94. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/sync/__init__.py +0 -0
  95. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/sync/auth.py +0 -0
  96. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/sync/event.py +0 -0
  97. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/sync/impression.py +0 -0
  98. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/sync/manager.py +0 -0
  99. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/sync/segment.py +0 -0
  100. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/sync/synchronizer.py +0 -0
  101. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/sync/telemetry.py +0 -0
  102. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/sync/unique_keys.py +0 -0
  103. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/sync/util.py +0 -0
  104. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/tasks/__init__.py +0 -0
  105. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/tasks/events_sync.py +0 -0
  106. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/tasks/impressions_sync.py +0 -0
  107. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/tasks/segment_sync.py +0 -0
  108. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/tasks/telemetry_sync.py +0 -0
  109. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/tasks/unique_keys_sync.py +0 -0
  110. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/tasks/util/__init__.py +0 -0
  111. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/tasks/util/asynctask.py +0 -0
  112. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/tasks/util/workerpool.py +0 -0
  113. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/util/__init__.py +0 -0
  114. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/util/backoff.py +0 -0
  115. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/util/decorators.py +0 -0
  116. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/util/input_validator.py +0 -0
  117. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/util/storage_helper.py +0 -0
  118. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/util/threadutil.py +0 -0
  119. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons/util/time.py +0 -0
  120. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons.egg-info/SOURCES.txt +0 -0
  121. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons.egg-info/dependency_links.txt +0 -0
  122. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons.egg-info/requires.txt +0 -0
  123. {splitio_commons-1.0.0 → splitio_commons-1.1.0}/splitio_commons.egg-info/top_level.txt +0 -0
@@ -1,4 +1,4 @@
1
- Harness Feature Management Python Commons Copyright 2024-2026 Harness Inc.
1
+ Harness Feature Management JavaScript SDK Copyright 2024-2026 Harness Inc.
2
2
 
3
3
  This product includes software developed at Harness Inc. (https://harness.io/).
4
4
 
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: splitio_commons
3
- Version: 1.0.0
4
- Summary: Splitio Python Commons
5
- Home-page: https://github.com/splitio/python-commons
6
- Download-URL: https://github.com/splitio/python-commons/tarball/1.0.0
3
+ Version: 1.1.0
4
+ Summary: harness.io Python Commons
5
+ Home-page: https://github.com/splitio_commons/python-commons
6
+ Download-URL: https://github.com/splitio_commons/python-commons/tarball/1.1.0
7
7
  Author: Bilal Al-Shahwany
8
8
  Author-email: bilal.al-shahwany@harness.io
9
9
  License: Apache License 2.0
@@ -37,11 +37,11 @@ with open(path.join(path.abspath(path.dirname(__file__)), 'splitio_commons', 've
37
37
  setup(
38
38
  name='splitio_commons',
39
39
  version=__version__, # pylint: disable=undefined-variable
40
- description='Splitio Python Commons',
40
+ description='harness.io Python Commons',
41
41
  author='Bilal Al-Shahwany',
42
42
  author_email='bilal.al-shahwany@harness.io',
43
- url='https://github.com/splitio/python-commons',
44
- download_url=('https://github.com/splitio/python-commons/tarball/' + __version__), # pylint: disable=undefined-variable
43
+ url='https://github.com/splitio_commons/python-commons',
44
+ download_url=('https://github.com/splitio_commons/python-commons/tarball/' + __version__), # pylint: disable=undefined-variable
45
45
  license='Apache License 2.0',
46
46
  install_requires=INSTALL_REQUIRES,
47
47
  tests_require=TESTS_REQUIRES,
@@ -52,6 +52,7 @@ class SegmentsAPI(object): # pylint: disable=too-few-public-methods
52
52
  :rtype: dict
53
53
  """
54
54
  try:
55
+ self._update_sdk_version_header()
55
56
  query, extra_headers = build_fetch(change_number, fetch_options, self._metadata)
56
57
  response = self._client.get(
57
58
  'sdk',
@@ -77,6 +78,8 @@ class SegmentsAPI(object): # pylint: disable=too-few-public-methods
77
78
  _LOGGER.debug('Error: ', exc_info=True)
78
79
  raise APIException('Segments not fetched properly.') from exc
79
80
 
81
+ def _update_sdk_version_header(self):
82
+ pass
80
83
 
81
84
  class SegmentsAPIAsync(object): # pylint: disable=too-few-public-methods
82
85
  """Async Class that uses an httpClient to communicate with the segments API."""
@@ -118,6 +121,7 @@ class SegmentsAPIAsync(object): # pylint: disable=too-few-public-methods
118
121
  :rtype: dict
119
122
  """
120
123
  try:
124
+ self._update_sdk_version_header()
121
125
  query, extra_headers = build_fetch(change_number, fetch_options, self._metadata)
122
126
  response = await self._client.get(
123
127
  'sdk',
@@ -142,3 +146,6 @@ class SegmentsAPIAsync(object): # pylint: disable=too-few-public-methods
142
146
  )
143
147
  _LOGGER.debug('Error: ', exc_info=True)
144
148
  raise APIException('Segments not fetched properly.') from exc
149
+
150
+ def _update_sdk_version_header(self):
151
+ pass
@@ -85,6 +85,9 @@ class SSEClient(object):
85
85
  event_builder = EventBuilder()
86
86
  else:
87
87
  event_builder.process_line(line)
88
+ except OSError:
89
+ _LOGGER.debug('sse connection ended.')
90
+ pass
88
91
  except Exception: # pylint:disable=broad-except
89
92
  _LOGGER.debug('sse connection ended.')
90
93
  _LOGGER.debug('stack trace: ', exc_info=True)
@@ -131,11 +134,10 @@ class SSEClient(object):
131
134
  if self._shutdown_requested:
132
135
  _LOGGER.warning("shutdown already requested")
133
136
  return
134
-
137
+ _LOGGER.debug("shutting down SSE")
135
138
  self._shutdown_requested = True
136
139
  self._conn.sock.shutdown(socket.SHUT_RDWR)
137
140
 
138
-
139
141
  class SSEClientAsync(object):
140
142
  """SSE Client implementation."""
141
143
 
@@ -6,6 +6,7 @@ import random
6
6
  from splitio_commons.models.telemetry import MethodExceptionsAndLatencies
7
7
  from splitio_commons.models import telemetry
8
8
  from splitio_commons.optional.loaders import asyncio
9
+ from splitio_commons.storage.inmemmory import MAX_SIZE_BYTES
9
10
 
10
11
  _LOGGER = logging.getLogger(__name__)
11
12
 
@@ -60,6 +61,9 @@ class StatsRecorder(object, metaclass=abc.ABCMeta):
60
61
  """
61
62
  pass
62
63
 
64
+ def _get_size(self, event):
65
+ return sum(ev.size for ev in event)
66
+
63
67
  class StatsRecorderThreadingBase(StatsRecorder):
64
68
  """StandardRecorder class."""
65
69
 
@@ -131,7 +135,7 @@ class StatsRecorderAsyncBase(StatsRecorder):
131
135
  class StandardRecorder(StatsRecorderThreadingBase):
132
136
  """StandardRecorder class."""
133
137
 
134
- def __init__(self, impressions_manager, event_storage, impression_storage, telemetry_evaluation_producer, telemetry_runtime_producer, listener=None, unique_keys_tracker=None, imp_counter=None):
138
+ def __init__(self, impression_queue_full_hook, event_queue_full_hook, impressions_manager, event_storage, impression_storage, telemetry_evaluation_producer, telemetry_runtime_producer, listener=None, unique_keys_tracker=None, imp_counter=None):
135
139
  """
136
140
  Class constructor.
137
141
 
@@ -149,6 +153,8 @@ class StandardRecorder(StatsRecorderThreadingBase):
149
153
  StatsRecorderThreadingBase.__init__(self, impressions_manager, event_storage, impression_storage, listener, unique_keys_tracker, imp_counter)
150
154
  self._telemetry_evaluation_producer = telemetry_evaluation_producer
151
155
  self._telemetry_runtime_producer = telemetry_runtime_producer
156
+ self._event_queue_full_hook = event_queue_full_hook
157
+ self._impression_queue_full_hook = impression_queue_full_hook
152
158
 
153
159
  def record_treatment_stats(self, impressions_decorated, latency, operation, method_name):
154
160
  """
@@ -167,7 +173,14 @@ class StandardRecorder(StatsRecorderThreadingBase):
167
173
  impressions, deduped, for_listener, for_counter, for_unique_keys_tracker = self._impressions_manager.process_impressions(impressions_decorated)
168
174
  if deduped > 0:
169
175
  self._telemetry_runtime_producer.record_impression_stats(telemetry.CounterConstants.IMPRESSIONS_DEDUPED, deduped)
170
- self._impression_storage.put(impressions)
176
+
177
+ for impression in impressions:
178
+ self._impression_storage.put([impression])
179
+
180
+ if self._impression_queue_full_hook != None:
181
+ if self._impression_storage._impressions.qsize() >= self._impression_storage._queue_size:
182
+ self._impression_queue_full_hook()
183
+
171
184
  self._send_impressions_to_listener(for_listener)
172
185
  if len(for_counter) > 0:
173
186
  self._imp_counter.track(for_counter)
@@ -185,12 +198,17 @@ class StandardRecorder(StatsRecorderThreadingBase):
185
198
  :type event: splitio_commons.models.events.EventWrapper
186
199
  """
187
200
  self._telemetry_evaluation_producer.record_latency(MethodExceptionsAndLatencies.TRACK, latency)
188
- return self._event_sotrage.put(event)
201
+
202
+ if self._event_queue_full_hook != None:
203
+ if self._event_sotrage._size + self._get_size(event) >= MAX_SIZE_BYTES or self._event_sotrage._events.qsize() + 1 >= self._event_sotrage._queue_size:
204
+ self._event_queue_full_hook()
189
205
 
206
+ return self._event_sotrage.put(event)
207
+
190
208
  class StandardRecorderAsync(StatsRecorderAsyncBase):
191
209
  """StandardRecorder async class."""
192
210
 
193
- def __init__(self, impressions_manager, event_storage, impression_storage, telemetry_evaluation_producer, telemetry_runtime_producer, listener=None, unique_keys_tracker=None, imp_counter=None):
211
+ def __init__(self, impression_queue_full_hook, event_queue_full_hook, impressions_manager, event_storage, impression_storage, telemetry_evaluation_producer, telemetry_runtime_producer, listener=None, unique_keys_tracker=None, imp_counter=None):
194
212
  """
195
213
  Class constructor.
196
214
 
@@ -208,6 +226,8 @@ class StandardRecorderAsync(StatsRecorderAsyncBase):
208
226
  StatsRecorderAsyncBase.__init__(self, impressions_manager, event_storage, impression_storage, listener, unique_keys_tracker, imp_counter)
209
227
  self._telemetry_evaluation_producer = telemetry_evaluation_producer
210
228
  self._telemetry_runtime_producer = telemetry_runtime_producer
229
+ self._event_queue_full_hook = event_queue_full_hook
230
+ self._impression_queue_full_hook = impression_queue_full_hook
211
231
 
212
232
  async def record_treatment_stats(self, impressions_decorated, latency, operation, method_name):
213
233
  """
@@ -227,7 +247,13 @@ class StandardRecorderAsync(StatsRecorderAsyncBase):
227
247
  if deduped > 0:
228
248
  await self._telemetry_runtime_producer.record_impression_stats(telemetry.CounterConstants.IMPRESSIONS_DEDUPED, deduped)
229
249
 
230
- await self._impression_storage.put(impressions)
250
+ for impression in impressions:
251
+ await self._impression_storage.put([impression])
252
+
253
+ if self._impression_queue_full_hook != None:
254
+ if self._impression_storage._impressions.qsize() >= self._impression_storage._queue_size:
255
+ await self._impression_queue_full_hook()
256
+
231
257
  await self._send_impressions_to_listener_async(for_listener)
232
258
  if len(for_counter) > 0:
233
259
  self._imp_counter.track(for_counter)
@@ -246,8 +272,15 @@ class StandardRecorderAsync(StatsRecorderAsyncBase):
246
272
  :type event: splitio_commons.models.events.EventWrapper
247
273
  """
248
274
  await self._telemetry_evaluation_producer.record_latency(MethodExceptionsAndLatencies.TRACK, latency)
249
- return await self._event_sotrage.put(event)
250
275
 
276
+ to_return = await self._event_sotrage.put(event)
277
+
278
+ if self._event_queue_full_hook != None:
279
+ if self._event_sotrage._size + self._get_size(event) >= MAX_SIZE_BYTES or self._event_sotrage._events.qsize() >= self._event_sotrage._queue_size:
280
+ await self._event_queue_full_hook()
281
+
282
+ return to_return
283
+
251
284
  class PipelinedRecorder(StatsRecorderThreadingBase):
252
285
  """PipelinedRecorder class."""
253
286
 
@@ -1323,8 +1323,6 @@ class InMemoryImpressionStorage(InMemoryImpressionStorageBase):
1323
1323
  except queue.Full:
1324
1324
  self._telemetry_runtime_producer.record_impression_stats(CounterConstants.IMPRESSIONS_DROPPED, len(impressions) - impressions_stored)
1325
1325
  self._telemetry_runtime_producer.record_impression_stats(CounterConstants.IMPRESSIONS_QUEUED, impressions_stored)
1326
- if self._queue_full_hook is not None and callable(self._queue_full_hook):
1327
- self._queue_full_hook()
1328
1326
  _LOGGER.warning(
1329
1327
  'Impression queue is full, failing to add more impressions. \n'
1330
1328
  'Consider increasing parameter `impressionsQueueSize` in configuration'
@@ -1381,6 +1379,7 @@ class InMemoryImpressionStorageAsync(InMemoryImpressionStorageBase):
1381
1379
  for impression in impressions:
1382
1380
  if self._impressions.qsize() == self._queue_size:
1383
1381
  raise asyncio.QueueFull
1382
+
1384
1383
  await self._impressions.put(impression)
1385
1384
  impressions_stored += 1
1386
1385
  await self._telemetry_runtime_producer.record_impression_stats(CounterConstants.IMPRESSIONS_QUEUED, len(impressions))
@@ -1389,8 +1388,6 @@ class InMemoryImpressionStorageAsync(InMemoryImpressionStorageBase):
1389
1388
  except asyncio.QueueFull:
1390
1389
  await self._telemetry_runtime_producer.record_impression_stats(CounterConstants.IMPRESSIONS_DROPPED, len(impressions) - impressions_stored)
1391
1390
  await self._telemetry_runtime_producer.record_impression_stats(CounterConstants.IMPRESSIONS_QUEUED, impressions_stored)
1392
- if self._queue_full_hook is not None and callable(self._queue_full_hook):
1393
- await self._queue_full_hook()
1394
1391
  _LOGGER.warning(
1395
1392
  'Impression queue is full, failing to add more impressions. \n'
1396
1393
  'Consider increasing parameter `impressionsQueueSize` in configuration'
@@ -1424,15 +1421,6 @@ class InMemoryEventStorageBase(EventStorage):
1424
1421
  In memory storage base class for events.
1425
1422
  Supports adding and popping events.
1426
1423
  """
1427
- def set_queue_full_hook(self, hook):
1428
- """
1429
- Set a hook to be called when the queue is full.
1430
-
1431
- :param h: Hook to be called when the queue is full
1432
- """
1433
- if callable(hook):
1434
- self._queue_full_hook = hook
1435
-
1436
1424
  def put(self, events):
1437
1425
  """
1438
1426
  Add an event to storage.
@@ -1472,7 +1460,6 @@ class InMemoryEventStorage(InMemoryEventStorageBase):
1472
1460
  self._queue_size = eventsQueueSize
1473
1461
  self._lock = threading.Lock()
1474
1462
  self._events = queue.Queue(maxsize=eventsQueueSize)
1475
- self._queue_full_hook = None
1476
1463
  self._size = 0
1477
1464
  self._telemetry_runtime_producer = telemetry_runtime_producer
1478
1465
 
@@ -1486,27 +1473,25 @@ class InMemoryEventStorage(InMemoryEventStorageBase):
1486
1473
  try:
1487
1474
  with self._lock:
1488
1475
  for event in events:
1489
- self._size += event.size
1490
-
1491
- if self._size >= MAX_SIZE_BYTES:
1492
- self._queue_full_hook()
1493
- return False
1494
-
1495
1476
  self._events.put(event.event, False)
1477
+ self._size += event.size
1496
1478
  events_stored += 1
1479
+
1497
1480
  self._telemetry_runtime_producer.record_event_stats(CounterConstants.EVENTS_QUEUED, len(events))
1498
1481
  return True
1499
1482
 
1500
1483
  except queue.Full:
1501
- self._telemetry_runtime_producer.record_event_stats(CounterConstants.EVENTS_DROPPED, len(events) - events_stored)
1502
- self._telemetry_runtime_producer.record_event_stats(CounterConstants.EVENTS_QUEUED, events_stored)
1503
- if self._queue_full_hook is not None and callable(self._queue_full_hook):
1504
- self._queue_full_hook()
1505
1484
  _LOGGER.warning(
1506
- 'Events queue is full, failing to add more events. \n'
1507
- 'Consider increasing parameter `eventsQueueSize` in configuration'
1485
+ 'Events queue is full, flushing storage events. \n'
1486
+ 'Consider increasing Queue Size parameter in configuration'
1508
1487
  )
1509
- return False
1488
+ except Exception:
1489
+ _LOGGER.error("Exception in storing events")
1490
+ _LOGGER.debug("Exception info: ", exc_info=True)
1491
+
1492
+ self._telemetry_runtime_producer.record_event_stats(CounterConstants.EVENTS_DROPPED, len(events) - events_stored)
1493
+ self._telemetry_runtime_producer.record_event_stats(CounterConstants.EVENTS_QUEUED, events_stored)
1494
+ return False
1510
1495
 
1511
1496
  def pop_many(self, count):
1512
1497
  """
@@ -1544,7 +1529,6 @@ class InMemoryEventStorageAsync(InMemoryEventStorageBase):
1544
1529
  self._queue_size = eventsQueueSize
1545
1530
  self._lock = asyncio.Lock()
1546
1531
  self._events = asyncio.Queue(maxsize=eventsQueueSize)
1547
- self._queue_full_hook = None
1548
1532
  self._size = 0
1549
1533
  self._telemetry_runtime_producer = telemetry_runtime_producer
1550
1534
 
@@ -1560,27 +1544,27 @@ class InMemoryEventStorageAsync(InMemoryEventStorageBase):
1560
1544
  for event in events:
1561
1545
  if self._events.qsize() == self._queue_size:
1562
1546
  raise asyncio.QueueFull
1563
-
1564
- self._size += event.size
1565
- if self._size >= MAX_SIZE_BYTES:
1566
- await self._queue_full_hook()
1567
- return False
1568
-
1547
+
1569
1548
  await self._events.put(event.event)
1549
+ self._size += event.size
1570
1550
  events_stored += 1
1551
+
1552
+ await self._telemetry_runtime_producer.record_event_stats(CounterConstants.EVENTS_DROPPED, len(events) - events_stored)
1571
1553
  await self._telemetry_runtime_producer.record_event_stats(CounterConstants.EVENTS_QUEUED, len(events))
1572
1554
  return True
1573
1555
 
1574
1556
  except asyncio.QueueFull:
1575
- await self._telemetry_runtime_producer.record_event_stats(CounterConstants.EVENTS_DROPPED, len(events) - events_stored)
1576
- await self._telemetry_runtime_producer.record_event_stats(CounterConstants.EVENTS_QUEUED, events_stored)
1577
- if self._queue_full_hook is not None and callable(self._queue_full_hook):
1578
- await self._queue_full_hook()
1579
1557
  _LOGGER.warning(
1580
1558
  'Events queue is full, failing to add more events. \n'
1581
1559
  'Consider increasing parameter `eventsQueueSize` in configuration'
1582
1560
  )
1583
- return False
1561
+ except Exception:
1562
+ _LOGGER.error("Exception in storing events")
1563
+ _LOGGER.debug("Exception info: ", exc_info=True)
1564
+
1565
+ await self._telemetry_runtime_producer.record_event_stats(CounterConstants.EVENTS_DROPPED, len(events) - events_stored)
1566
+ await self._telemetry_runtime_producer.record_event_stats(CounterConstants.EVENTS_QUEUED, events_stored)
1567
+ return False
1584
1568
 
1585
1569
  async def pop_many(self, count):
1586
1570
  """
@@ -66,8 +66,8 @@ class DefinitionSynchronizerBase(object):
66
66
  def _check_exit_conditions(self, till, rbs_till, change_number, rbs_change_number):
67
67
  return (till is not None and till < change_number) or (rbs_till is not None and rbs_till < rbs_change_number)
68
68
 
69
- def _check_return_conditions(self, definition_changes):
70
- return definition_changes.get(self._definition_json_section_name)['t'] == definition_changes.get(self._definition_json_section_name)['s'] and definition_changes.get('rbs')['t'] == definition_changes.get('rbs')['s']
69
+ def _check_return_conditions(self, definition_changes, till, rbs_till):
70
+ return (definition_changes.get(self._definition_json_section_name)['t'] == definition_changes.get(self._definition_json_section_name)['s'] and definition_changes.get('rbs')['t'] == definition_changes.get('rbs')['s']) or (till is None and rbs_till is None)
71
71
 
72
72
  def _update_definition_if_needed(self, definition_changes):
73
73
  # Call used to inject any changed needed
@@ -144,7 +144,7 @@ class DefinitionSynchronizer(DefinitionSynchronizerBase):
144
144
  segment_list.update(update_definition_storage(self._definition_storage, fetched_definitions, definition_changes.get(self._definition_json_section_name)['t'], self._api.clear_storage))
145
145
  segment_list.update(rbs_segment_list)
146
146
 
147
- if self._check_return_conditions(definition_changes):
147
+ if self._check_return_conditions(definition_changes, till, rbs_till):
148
148
  return definition_changes.get(self._definition_json_section_name)['t'], definition_changes.get('rbs')['t'], segment_list
149
149
 
150
150
  def _attempt_definition_sync(self, fetch_options, till=None, rbs_till=None):
@@ -293,7 +293,7 @@ class DefinitionSynchronizerAsync(DefinitionSynchronizerBase):
293
293
  segment_list = await update_definition_storage_async(self._definition_storage, fetched_definitions, definition_changes.get(self._definition_json_section_name)['t'], self._api.clear_storage)
294
294
  segment_list.update(rbs_segment_list)
295
295
 
296
- if self._check_return_conditions(definition_changes):
296
+ if self._check_return_conditions(definition_changes, till, rbs_till):
297
297
  return definition_changes.get(self._definition_json_section_name)['t'], definition_changes.get('rbs')['t'], segment_list
298
298
 
299
299
  async def _attempt_definition_sync(self, fetch_options, till=None, rbs_till=None):
@@ -0,0 +1 @@
1
+ __version__ = '1.1.0'
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: splitio-commons
3
- Version: 1.0.0
4
- Summary: Splitio Python Commons
5
- Home-page: https://github.com/splitio/python-commons
6
- Download-URL: https://github.com/splitio/python-commons/tarball/1.0.0
3
+ Version: 1.1.0
4
+ Summary: harness.io Python Commons
5
+ Home-page: https://github.com/splitio_commons/python-commons
6
+ Download-URL: https://github.com/splitio_commons/python-commons/tarball/1.1.0
7
7
  Author: Bilal Al-Shahwany
8
8
  Author-email: bilal.al-shahwany@harness.io
9
9
  License: Apache License 2.0
@@ -1 +0,0 @@
1
- __version__ = '1.0.0'