sentry-arroyo 2.32.5__py3-none-any.whl → 2.33.1__py3-none-any.whl

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.
@@ -237,8 +237,7 @@ def build_kafka_consumer_configuration(
237
237
  bootstrap_servers: Optional[Sequence[str]] = None,
238
238
  override_params: Optional[Mapping[str, Any]] = None,
239
239
  strict_offset_reset: Optional[bool] = None,
240
- enable_auto_commit: bool = False,
241
- retry_handle_destroyed: bool = False,
240
+ enable_auto_commit: bool = True,
242
241
  ) -> KafkaBrokerConfig:
243
242
 
244
243
  if auto_offset_reset is None:
@@ -264,8 +263,6 @@ def build_kafka_consumer_configuration(
264
263
  "arroyo.strict.offset.reset": strict_offset_reset,
265
264
  # this is an arroyo specific flag to enable auto-commit mode
266
265
  "arroyo.enable.auto.commit": enable_auto_commit,
267
- # arroyo specific flag to enable retries when hitting `KafkaError._DESTROY` while committing
268
- "arroyo.retry.broker.handle.destroyed": retry_handle_destroyed,
269
266
  # overridden to reduce memory usage when there's a large backlog
270
267
  "queued.max.messages.kbytes": queued_max_messages_kbytes,
271
268
  "queued.min.messages": queued_min_messages,
@@ -159,22 +159,13 @@ class KafkaConsumer(Consumer[KafkaPayload]):
159
159
  ) -> None:
160
160
  configuration = dict(configuration)
161
161
 
162
- # Feature flag to enable retrying on `Broker handle destroyed` errors
163
- # which can occur if we attempt to commit during a rebalance when
164
- # the consumer group coordinator changed
165
- self.__retry_handle_destroyed = as_kafka_configuration_bool(
166
- configuration.pop("arroyo.retry.broker.handle.destroyed", False)
167
- )
168
-
169
- retryable_errors: Tuple[int, ...] = (
162
+ retryable_errors = (
170
163
  KafkaError.REQUEST_TIMED_OUT,
171
164
  KafkaError.NOT_COORDINATOR,
172
165
  KafkaError._WAIT_COORD,
173
166
  KafkaError.STALE_MEMBER_EPOCH, # kip-848
174
167
  KafkaError.COORDINATOR_LOAD_IN_PROGRESS,
175
168
  )
176
- if self.__retry_handle_destroyed:
177
- retryable_errors += (KafkaError._DESTROY,)
178
169
 
179
170
  commit_retry_policy = BasicRetryPolicy(
180
171
  3,
@@ -140,8 +140,6 @@ class StreamProcessor(Generic[TStrategyPayload]):
140
140
  commit_policy: CommitPolicy = ONCE_PER_SECOND,
141
141
  dlq_policy: Optional[DlqPolicy[TStrategyPayload]] = None,
142
142
  join_timeout: Optional[float] = None,
143
- shutdown_strategy_before_consumer: bool = False,
144
- handle_poll_while_paused: Optional[bool] = False,
145
143
  ) -> None:
146
144
  self.__consumer = consumer
147
145
  self.__processor_factory = processor_factory
@@ -166,9 +164,6 @@ class StreamProcessor(Generic[TStrategyPayload]):
166
164
  )
167
165
 
168
166
  self.__shutdown_requested = False
169
- self.__shutdown_strategy_before_consumer = shutdown_strategy_before_consumer
170
-
171
- self.__handle_poll_while_paused = handle_poll_while_paused
172
167
 
173
168
  # Buffers messages for DLQ. Messages are added when they are submitted for processing and
174
169
  # removed once the commit callback is fired as they are guaranteed to be valid at that point.
@@ -386,9 +381,12 @@ class StreamProcessor(Generic[TStrategyPayload]):
386
381
  start_dlq = time.time()
387
382
  invalid_message = self.__buffered_messages.pop(exc.partition, exc.offset)
388
383
  if invalid_message is None:
389
- raise Exception(
390
- f"Invalid message not found in buffer {exc.partition} {exc.offset}",
391
- ) from None
384
+ logger.error(
385
+ "Invalid message not found in buffer %s %s",
386
+ exc.partition,
387
+ exc.offset,
388
+ )
389
+ return
392
390
 
393
391
  # XXX: This blocks if there are more than MAX_PENDING_FUTURES in the queue.
394
392
  try:
@@ -467,58 +465,19 @@ class StreamProcessor(Generic[TStrategyPayload]):
467
465
  self.__is_paused = True
468
466
 
469
467
  elif self.__is_paused:
470
- if self.__handle_poll_while_paused:
471
- maybe_message = self.__consumer.poll(0.1)
472
- if maybe_message is not None:
473
- # The paused consumer, in the above poll, has
474
- # gone through rebalancing. In this case we
475
- # expect that partition revocation cleared the
476
- # pause flag and the carried over message.
477
- # this assumption will not hold for cooperative-sticky rebalancing.
478
- assert (
479
- not self.__is_paused
480
- ), "consumer unpaused itself without rebalancing"
481
- assert (
482
- self.__message is None
483
- ), "consumer unpaused itself without rebalancing"
484
- # this path might raise AssertionErrors
485
- else:
486
- paused_partitions = set(self.__consumer.paused())
487
- all_partitions = set(self.__consumer.tell())
488
- unpaused_partitions = all_partitions - paused_partitions
489
- if unpaused_partitions:
490
- logger.warning(
491
- "Processor in paused state while consumer is partially unpaused: %s, paused: %s",
492
- unpaused_partitions,
493
- paused_partitions,
494
- )
495
- self.__is_paused = False
496
- # unpause paused partitions... just in case a subset is paused
497
- self.__metrics_buffer.incr_counter(
498
- "arroyo.consumer.resume", 1
499
- )
500
- self.__consumer.resume([*paused_partitions])
501
- else:
502
- # A paused consumer should still poll periodically to avoid it's partitions
503
- # getting revoked by the broker after reaching the max.poll.interval.ms
504
- # Polling a paused consumer should never yield a message.
505
- logger.warning(
506
- "consumer.tell() value right before poll() is: %s",
507
- self.__consumer.tell(),
508
- )
509
- maybe_message = self.__consumer.poll(0.1)
510
- if maybe_message is not None:
511
- logger.warning(
512
- "Received a message from partition: %s, \
513
- consumer.tell() value right after poll() is: %s \
514
- Some lines above consumer.tell() was called, all_partitons value was: %s \
515
- Some lines above consumer.paused() was called, paused_partitions value is: %s",
516
- maybe_message.partition,
517
- self.__consumer.tell(),
518
- all_partitions,
519
- paused_partitions,
520
- )
521
- assert maybe_message is None
468
+ maybe_message = self.__consumer.poll(0.1)
469
+ if maybe_message is not None:
470
+ # The paused consumer, in the above poll, has
471
+ # gone through rebalancing. In this case we
472
+ # expect that partition revocation cleared the
473
+ # pause flag and the carried over message.
474
+ # this assumption will not hold for cooperative-sticky rebalancing.
475
+ assert (
476
+ not self.__is_paused
477
+ ), "consumer unpaused itself without rebalancing"
478
+ assert (
479
+ self.__message is None
480
+ ), "consumer unpaused itself without rebalancing"
522
481
 
523
482
  else:
524
483
  time.sleep(0.01)
@@ -560,12 +519,11 @@ class StreamProcessor(Generic[TStrategyPayload]):
560
519
  self.__shutdown_requested = True
561
520
 
562
521
  def _shutdown(self) -> None:
563
- # If shutdown_strategy_before_consumer is set, work around an issue
564
- # where rdkafka would revoke our partition, but then also immediately
565
- # revoke our member ID as well, causing join() of the CommitStrategy
566
- # (that is running in the partition revocation callback) to crash.
567
- if self.__shutdown_strategy_before_consumer:
568
- self._close_processing_strategy()
522
+ # when we close() a consumer, rdkafka would would revoke our partition
523
+ # and call revocation callbacks, but also immediately revoke our member
524
+ # ID as well, causing join() of the CommitStrategy (that is running in
525
+ # the partition revocation callback) to crash.
526
+ self._close_processing_strategy()
569
527
 
570
528
  # close the consumer
571
529
  logger.info("Stopping consumer")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sentry-arroyo
3
- Version: 2.32.5
3
+ Version: 2.33.1
4
4
  Summary: Arroyo is a Python library for working with streaming data.
5
5
  Home-page: https://github.com/getsentry/arroyo
6
6
  Author: Sentry
@@ -8,15 +8,15 @@ arroyo/backends/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  arroyo/backends/abstract.py,sha256=Wy9xhE1dtFiumG8Cz3JhksJ0rF74uJWZWq10UO1rxOI,9524
9
9
  arroyo/backends/kafka/__init__.py,sha256=xgf-AqHbQkJsh73YokO2uoyyHfZf8XwUp6BULtM8stI,445
10
10
  arroyo/backends/kafka/commit.py,sha256=LPsjvX5PPXR62DT6sa5GuSF78qk9F_L--Fz4kw7-m-s,3060
11
- arroyo/backends/kafka/configuration.py,sha256=42FQyrpIQGRaECBPljSaNO8E1RRyEoG1-a5cg3PwRe0,9356
12
- arroyo/backends/kafka/consumer.py,sha256=dzypkibGGieLg819TOoxtbVpVaxKYF9dazorQv5FxPg,34688
11
+ arroyo/backends/kafka/configuration.py,sha256=voSOnySPlIjmd9LafpnfE_X4s2Bkxd6YTpdsTiZ2CNk,9140
12
+ arroyo/backends/kafka/consumer.py,sha256=6exjpmSQxWVAdFCz52iIFQW3l3to-eJl9rCumY65e1o,34216
13
13
  arroyo/backends/local/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  arroyo/backends/local/backend.py,sha256=hUXdCV6B5e7s4mjFC6HnIuUhjENU2tNZt5vuEOJmGZQ,13888
15
15
  arroyo/backends/local/storages/__init__.py,sha256=AGYujdAAcn3osoj9jq84IzTywYbkIDv9wRg2rLhLXeg,104
16
16
  arroyo/backends/local/storages/abstract.py,sha256=1qVQp6roxHkK6XT2aklZyZk1qq7RzcPN6Db_CA5--kg,2901
17
17
  arroyo/backends/local/storages/memory.py,sha256=AoKDsVZzBXkOJyWArKWp3vfGfU9xLlKFXE9gsJiMIzQ,2613
18
18
  arroyo/processing/__init__.py,sha256=vZVg0wJvJfoVzlzGvnL59bT6YNIRJNQ5t7oU045Qbk4,87
19
- arroyo/processing/processor.py,sha256=CHBvpAxH6T3MrUtoCJR7nTFJppqmIAx0DTosADrUAEM,23711
19
+ arroyo/processing/processor.py,sha256=yEsA4WRhWoGJN9YVZVxOu52cIXEuriSbWV46HLNUX-I,20685
20
20
  arroyo/processing/strategies/__init__.py,sha256=EU_JMb54eOxMxaC5mIFpI-sAF-X2ZScbE8czBZ7bQkY,1106
21
21
  arroyo/processing/strategies/abstract.py,sha256=nu7juEz_aQmQIH35Z8u--FBuLjkK8_LQ1hIG2xpw9AA,4808
22
22
  arroyo/processing/strategies/batching.py,sha256=s89xC6lQpBseEaApu1iNTipXGKeO95OMwinj2VBKn9s,4778
@@ -46,17 +46,17 @@ examples/transform_and_produce/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5
46
46
  examples/transform_and_produce/batched.py,sha256=st2R6qTneAtV0JFbKP30Ti3sJDYj8Jkbmta9JckKdZU,2636
47
47
  examples/transform_and_produce/script.py,sha256=8kSMIjQNqGYEVyE0PvrfJh-a_UYCrJSstTp_De7kyyg,2306
48
48
  examples/transform_and_produce/simple.py,sha256=H7xqxItjl4tx34wVW5dy6mB9G39QucAtxkJSBzVmjgA,1637
49
- sentry_arroyo-2.32.5.dist-info/licenses/LICENSE,sha256=0Ng3MFdEcnz0sVD1XvGBBzbavvNp_7OAM5yVObB46jU,10829
49
+ sentry_arroyo-2.33.1.dist-info/licenses/LICENSE,sha256=0Ng3MFdEcnz0sVD1XvGBBzbavvNp_7OAM5yVObB46jU,10829
50
50
  tests/backends/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
51
51
  tests/backends/mixins.py,sha256=sfNyE0VTeiD3GHOnBYl-9urvPuURI2G1BWke0cz7Dvc,20445
52
52
  tests/backends/test_commit.py,sha256=iTHfK1qsBxim0XwxgMvNNSMqDUMEHoYkYBDcgxGBFbs,831
53
53
  tests/backends/test_confluent_producer.py,sha256=KWqgvjDvqAdd0HxngdWKsUJaV7Hl1L5vAVQhBYlHeHU,3146
54
- tests/backends/test_kafka.py,sha256=I5TOC1R1usWGyd4r3C9W_W6lbeKRVID1m5CaW6Vi4lM,18780
54
+ tests/backends/test_kafka.py,sha256=YL6CAPW8EtAJpjMhY71tyqHwcKtVkruB9cRCj9xx0Dk,18658
55
55
  tests/backends/test_kafka_commit_callback.py,sha256=svpY3T7FvhXvz2jp729e60LLn8MyFa8w88FQ1Y0Ursw,1987
56
56
  tests/backends/test_kafka_producer.py,sha256=LpwkqnstcCDxemlKZ0FpzNKrP-1UuXXY15P7P-spjhE,3912
57
57
  tests/backends/test_local.py,sha256=Mfd4DFuWVSVtl1GomQ6TIoWuJNcAliKqKU0BShPlEMY,3363
58
58
  tests/processing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
- tests/processing/test_processor.py,sha256=Ku_3z5aUeCRPRfeltHTSDLUMiATWmM_UXylhbE4kupg,25963
59
+ tests/processing/test_processor.py,sha256=f4WsNBo8RfNK2sPGWnwoJie1vfgaf74W1VAaazojwJ8,25934
60
60
  tests/processing/strategies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
61
61
  tests/processing/strategies/test_all.py,sha256=ahAF-nbdmqVkYGNCg0OFCD6fzNTA-XxYrW8NQHajCDU,10167
62
62
  tests/processing/strategies/test_batching.py,sha256=nyyX0y6qYHX7jT4gCgsUjT5RzBMDrBp790SCmOizQ0Q,11787
@@ -75,7 +75,7 @@ tests/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
75
75
  tests/utils/test_concurrent.py,sha256=Gwdzym2UZ1HO3rhOSGmzxImWcLFygY8P7MXHT3Q0xTE,455
76
76
  tests/utils/test_metrics.py,sha256=bI0EtGgPokMQyEqX58i0-8zvLfxRP2nWaWr2wLMaJ_o,917
77
77
  tests/utils/test_retries.py,sha256=AxJLkXWeL9AjHv_p1n0pe8CXXJp24ZQIuYBHfNcmiz4,3075
78
- sentry_arroyo-2.32.5.dist-info/METADATA,sha256=Ld6VXfYDMWphFkcbBijnnHx4GebcIT91If8tqP_6Tho,2208
79
- sentry_arroyo-2.32.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
80
- sentry_arroyo-2.32.5.dist-info/top_level.txt,sha256=DVdMZKysL_iIxm5aY0sYgZtP5ZXMg9YBaBmGQHVmDXA,22
81
- sentry_arroyo-2.32.5.dist-info/RECORD,,
78
+ sentry_arroyo-2.33.1.dist-info/METADATA,sha256=3HGQ4TfTltxOTm50ADT6zxGKvp2arBF6MFjzk1Wt4cs,2208
79
+ sentry_arroyo-2.33.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
80
+ sentry_arroyo-2.33.1.dist-info/top_level.txt,sha256=DVdMZKysL_iIxm5aY0sYgZtP5ZXMg9YBaBmGQHVmDXA,22
81
+ sentry_arroyo-2.33.1.dist-info/RECORD,,
@@ -261,9 +261,7 @@ class TestKafkaStreams(StreamsTestMixin[KafkaPayload]):
261
261
  timeout=5.0
262
262
  )
263
263
 
264
- processor_a = StreamProcessor(
265
- consumer_a, topic, factory, IMMEDIATE, handle_poll_while_paused=True
266
- )
264
+ processor_a = StreamProcessor(consumer_a, topic, factory, IMMEDIATE)
267
265
 
268
266
  def wait_until_consumer_pauses(processor: StreamProcessor[Any]) -> None:
269
267
  for _ in range(20):
@@ -289,9 +287,7 @@ class TestKafkaStreams(StreamsTestMixin[KafkaPayload]):
289
287
  assert processor_a._StreamProcessor__is_paused is True # type:ignore
290
288
 
291
289
  # subscribe with another consumer, now we should have rebalancing in the next few polls
292
- processor_b = StreamProcessor(
293
- consumer_b, topic, factory, IMMEDIATE, handle_poll_while_paused=True
294
- )
290
+ processor_b = StreamProcessor(consumer_b, topic, factory, IMMEDIATE)
295
291
 
296
292
  for _ in range(10):
297
293
  try:
@@ -691,6 +691,7 @@ def test_processor_pause_with_invalid_message() -> None:
691
691
  processor._run_once()
692
692
  assert strategy.submit.call_args_list[-1] == mock.call(new_message)
693
693
 
694
+
694
695
  def test_processor_poll_while_paused() -> None:
695
696
 
696
697
  topic = Topic("topic")
@@ -701,7 +702,7 @@ def test_processor_poll_while_paused() -> None:
701
702
  factory.create_with_partitions.return_value = strategy
702
703
 
703
704
  processor: StreamProcessor[int] = StreamProcessor(
704
- consumer, topic, factory, IMMEDIATE, handle_poll_while_paused=True
705
+ consumer, topic, factory, IMMEDIATE
705
706
  )
706
707
 
707
708
  # Subscribe to topic
@@ -755,7 +756,7 @@ def test_processor_poll_while_paused() -> None:
755
756
  new_message = Message(BrokerValue(0, new_partition, 1, datetime.now()))
756
757
  consumer.poll.return_value = new_message.value
757
758
  processor._run_once()
758
- assert processor._StreamProcessor__is_paused is False # type:ignore
759
+ assert processor._StreamProcessor__is_paused is False # type:ignore
759
760
 
760
761
  strategy.submit.return_value = None
761
762
  strategy.submit.side_effect = None