sentry-arroyo 2.19.12__py3-none-any.whl → 2.20.0__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.
arroyo/dlq.py CHANGED
@@ -28,6 +28,7 @@ from arroyo.types import (
28
28
  TStrategyPayload,
29
29
  Value,
30
30
  )
31
+ from arroyo.utils.metrics import get_metrics
31
32
 
32
33
  logger = logging.getLogger(__name__)
33
34
 
@@ -287,6 +288,11 @@ class BufferedMessages(Generic[TStrategyPayload]):
287
288
  self.__buffered_messages: MutableMapping[
288
289
  Partition, Deque[BrokerValue[TStrategyPayload]]
289
290
  ] = defaultdict(deque)
291
+ self.__metrics = get_metrics()
292
+
293
+ def report_partition_metrics(self, buffered: Deque[BrokerValue[TStrategyPayload]]) -> None:
294
+
295
+ self.__metrics.gauge("arroyo.consumer.dlq_buffer.len", len(buffered))
290
296
 
291
297
  def append(self, message: BrokerValue[TStrategyPayload]) -> None:
292
298
  """
@@ -304,6 +310,7 @@ class BufferedMessages(Generic[TStrategyPayload]):
304
310
  buffered.popleft()
305
311
 
306
312
  self.__buffered_messages[message.partition].append(message)
313
+ self.report_partition_metrics(self.__buffered_messages[message.partition])
307
314
 
308
315
  def pop(
309
316
  self, partition: Partition, offset: int
@@ -317,9 +324,14 @@ class BufferedMessages(Generic[TStrategyPayload]):
317
324
 
318
325
  while buffered:
319
326
  if buffered[0].offset == offset:
320
- return buffered.popleft()
327
+ msg = buffered.popleft()
328
+ self.report_partition_metrics(buffered)
329
+ return msg
321
330
  if buffered[0].offset > offset:
331
+ self.report_partition_metrics(buffered)
322
332
  break
333
+
334
+ self.report_partition_metrics(buffered)
323
335
  self.__buffered_messages[partition].popleft()
324
336
 
325
337
  return None
@@ -3,7 +3,7 @@ from collections import deque
3
3
  from typing import Callable, Deque, Generic, Iterable, Optional, TypeVar, Union, cast
4
4
 
5
5
  from arroyo.processing.strategies.abstract import MessageRejected, ProcessingStrategy
6
- from arroyo.types import BaseValue, FilteredPayload, Message
6
+ from arroyo.types import BaseValue, FilteredPayload, Message, Value
7
7
 
8
8
  TInput = TypeVar("TInput")
9
9
  TOutput = TypeVar("TOutput")
@@ -17,9 +17,20 @@ class Unfold(
17
17
  messages submitting them one by one to the next step. The generated
18
18
  messages are created according to the generator function provided by the user.
19
19
 
20
+ ::
21
+
22
+ def generator(num: int) -> Sequence[Value[int]]:
23
+ return [Value(i, {}, None) for i in range(num)]
24
+
25
+ unfold = Unfold(generator, next_step)
26
+
20
27
  The generator function provided must return an iterable (i.e. a class that
21
28
  implements `__iter__` ).
22
29
 
30
+ The generator can choose to set its own committable on the return value. If
31
+ the `committable` is empty, `Unfold` will use the offsets of the
32
+ original message.
33
+
23
34
  If this step receives a `MessageRejected` exception from the next
24
35
  step it keeps the remaining messages and attempts to submit
25
36
  them on subsequent calls to `poll`
@@ -47,12 +58,23 @@ class Unfold(
47
58
  )
48
59
  return
49
60
 
50
- iterable = self.__generator(message.payload)
61
+ iterable = list(self.__generator(message.payload))
62
+ num_messages = len(iterable)
51
63
 
52
64
  store_remaining_messages = False
53
65
 
54
- for value in iterable:
66
+ for i, value in enumerate(iterable):
55
67
  next_message = Message(value=value)
68
+ # If generator did not provide committable, patch our own
69
+ # committable onto it
70
+ if i == num_messages - 1 and not next_message.committable:
71
+ next_message = Message(
72
+ Value(
73
+ next_message.payload,
74
+ message.committable,
75
+ next_message.timestamp,
76
+ )
77
+ )
56
78
 
57
79
  if store_remaining_messages == False:
58
80
  try:
@@ -1 +1 @@
1
- {"arroyo.strategies.run_task_with_multiprocessing.batch.size.msg": {"name": "arroyo.strategies.run_task_with_multiprocessing.batch.size.msg", "type": "Time", "description": "Number of messages in a multiprocessing batch"}, "arroyo.strategies.run_task_with_multiprocessing.batch.size.bytes": {"name": "arroyo.strategies.run_task_with_multiprocessing.batch.size.bytes", "type": "Time", "description": "Number of bytes in a multiprocessing batch"}, "arroyo.strategies.run_task_with_multiprocessing.output_batch.size.msg": {"name": "arroyo.strategies.run_task_with_multiprocessing.output_batch.size.msg", "type": "Time", "description": "Number of messages in a multiprocessing batch after the message transformation"}, "arroyo.strategies.run_task_with_multiprocessing.output_batch.size.bytes": {"name": "arroyo.strategies.run_task_with_multiprocessing.output_batch.size.bytes", "type": "Time", "description": "Number of bytes in a multiprocessing batch after the message transformation"}, "arroyo.consumer.run.count": {"name": "arroyo.consumer.run.count", "type": "Counter", "description": "Number of times the consumer is spinning"}, "arroyo.consumer.invalid_message.count": {"name": "arroyo.consumer.invalid_message.count", "type": "Counter", "description": "Number of times the consumer encountered an invalid message."}, "arroyo.strategies.reduce.batch_time": {"name": "arroyo.strategies.reduce.batch_time", "type": "Time", "description": "How long it took the Reduce step to fill up a batch"}, "arroyo.strategies.run_task_with_multiprocessing.batch.backpressure": {"name": "arroyo.strategies.run_task_with_multiprocessing.batch.backpressure", "type": "Counter", "description": "Incremented when a strategy after multiprocessing applies\nbackpressure to multiprocessing. May be a reason why CPU cannot be\nsaturated."}, "arroyo.strategies.run_task_with_multiprocessing.batch.input.overflow": {"name": "arroyo.strategies.run_task_with_multiprocessing.batch.input.overflow", "type": "Counter", "description": "Incremented when multiprocessing cannot fill the input batch\nbecause not enough memory was allocated. This results in batches smaller\nthan configured. Increase `input_block_size` to fix."}, "arroyo.strategies.run_task_with_multiprocessing.batch.output.overflow": {"name": "arroyo.strategies.run_task_with_multiprocessing.batch.output.overflow", "type": "Counter", "description": "Incremented when multiprocessing cannot pull results in batches\nequal to the input batch size, because not enough memory was allocated.\nThis can be devastating for throughput. Increase `output_block_size` to\nfix."}, "arroyo.strategies.run_task_with_multiprocessing.batch.input.resize": {"name": "arroyo.strategies.run_task_with_multiprocessing.batch.input.resize", "type": "Counter", "description": "Arroyo has decided to re-allocate a block in order to combat input\nbuffer overflow. This behavior can be disabled by explicitly setting\n`input_block_size` to a not-None value in `RunTaskWithMultiprocessing`."}, "arroyo.strategies.run_task_with_multiprocessing.batch.output.resize": {"name": "arroyo.strategies.run_task_with_multiprocessing.batch.output.resize", "type": "Counter", "description": "Arroyo has decided to re-allocate a block in order to combat output\nbuffer overflow. This behavior can be disabled by explicitly setting\n`output_block_size` to a not-None value in `RunTaskWithMultiprocessing`."}, "arroyo.strategies.run_task_with_multiprocessing.batches_in_progress": {"name": "arroyo.strategies.run_task_with_multiprocessing.batches_in_progress", "type": "Gauge", "description": "How many batches are being processed in parallel by multiprocessing."}, "arroyo.strategies.run_task_with_multiprocessing.processes": {"name": "arroyo.strategies.run_task_with_multiprocessing.processes", "type": "Counter", "description": "A subprocess by multiprocessing unexpectedly died.\n\"sigchld.detected\",\nGauge: Shows how many processes the multiprocessing strategy is\nconfigured with."}, "arroyo.strategies.run_task_with_multiprocessing.pool.create": {"name": "arroyo.strategies.run_task_with_multiprocessing.pool.create", "type": "Counter", "description": "Incremented when the multiprocessing pool is created (or re-created)."}, "arroyo.consumer.poll.time": {"name": "arroyo.consumer.poll.time", "type": "Time", "description": "(unitless) spent polling librdkafka for new messages."}, "arroyo.consumer.processing.time": {"name": "arroyo.consumer.processing.time", "type": "Time", "description": "(unitless) spent in strategies (blocking in strategy.submit or\nstrategy.poll)"}, "arroyo.consumer.backpressure.time": {"name": "arroyo.consumer.backpressure.time", "type": "Time", "description": "(unitless) spent pausing the consumer due to backpressure (MessageRejected)"}, "arroyo.consumer.dlq.time": {"name": "arroyo.consumer.dlq.time", "type": "Time", "description": "(unitless) spent in handling `InvalidMessage` exceptions and sending\nmessages to the the DLQ."}, "arroyo.consumer.join.time": {"name": "arroyo.consumer.join.time", "type": "Time", "description": "(unitless) spent in waiting for the strategy to exit, such as during\nshutdown or rebalancing."}, "arroyo.consumer.callback.time": {"name": "arroyo.consumer.callback.time", "type": "Time", "description": "(unitless) spent in librdkafka callbacks. This metric's timings\noverlap other timings, and might spike at the same time."}, "arroyo.consumer.shutdown.time": {"name": "arroyo.consumer.shutdown.time", "type": "Time", "description": "(unitless) spent in shutting down the consumer. This metric's\ntimings overlap other timings, and might spike at the same time."}, "arroyo.consumer.run.callback": {"name": "arroyo.consumer.run.callback", "type": "Time", "description": "A regular duration metric where each datapoint is measuring the time it\ntook to execute a single callback. This metric is distinct from the\narroyo.consumer.*.time metrics as it does not attempt to accumulate time\nspent per second in an attempt to keep monitoring overhead low.\nThe metric is tagged by the name of the internal callback function being\nexecuted, as 'callback_name'. Possible values are on_partitions_assigned\nand on_partitions_revoked."}, "arroyo.consumer.run.close_strategy": {"name": "arroyo.consumer.run.close_strategy", "type": "Time", "description": "Duration metric measuring the time it took to flush in-flight messages\nand shut down the strategies."}, "arroyo.consumer.run.create_strategy": {"name": "arroyo.consumer.run.create_strategy", "type": "Time", "description": "Duration metric measuring the time it took to create the processing strategy."}, "arroyo.consumer.partitions_revoked.count": {"name": "arroyo.consumer.partitions_revoked.count", "type": "Counter", "description": "How many partitions have been revoked just now."}, "arroyo.consumer.partitions_assigned.count": {"name": "arroyo.consumer.partitions_assigned.count", "type": "Counter", "description": "How many partitions have been assigned just now."}, "arroyo.consumer.latency": {"name": "arroyo.consumer.latency", "type": "Time", "description": "Consumer latency in seconds. Recorded by the commit offsets strategy."}, "arroyo.consumer.pause": {"name": "arroyo.consumer.pause", "type": "Counter", "description": "Metric for when the underlying rdkafka consumer is being paused.\nThis flushes internal prefetch buffers."}, "arroyo.consumer.resume": {"name": "arroyo.consumer.resume", "type": "Counter", "description": "Metric for when the underlying rdkafka consumer is being resumed.\nThis might cause increased network usage as messages are being re-fetched."}, "arroyo.consumer.librdkafka.total_queue_size": {"name": "arroyo.consumer.librdkafka.total_queue_size", "type": "Gauge", "description": "Queue size of background queue that librdkafka uses to prefetch messages."}, "arroyo.processing.strategies.healthcheck.touch": {"name": "arroyo.processing.strategies.healthcheck.touch", "type": "Counter", "description": "Counter metric to measure how often the healthcheck file has been touched."}, "arroyo.strategies.filter.dropped_messages": {"name": "arroyo.strategies.filter.dropped_messages", "type": "Counter", "description": "Number of messages dropped in the FilterStep strategy"}, "arroyo.consumer.dlq.dropped_messages": {"name": "arroyo.consumer.dlq.dropped_messages", "type": "Counter", "description": "how many messages are dropped due to errors producing to the dlq"}}
1
+ {"arroyo.strategies.run_task_with_multiprocessing.batch.size.msg": {"name": "arroyo.strategies.run_task_with_multiprocessing.batch.size.msg", "type": "Time", "description": "Number of messages in a multiprocessing batch"}, "arroyo.strategies.run_task_with_multiprocessing.batch.size.bytes": {"name": "arroyo.strategies.run_task_with_multiprocessing.batch.size.bytes", "type": "Time", "description": "Number of bytes in a multiprocessing batch"}, "arroyo.strategies.run_task_with_multiprocessing.output_batch.size.msg": {"name": "arroyo.strategies.run_task_with_multiprocessing.output_batch.size.msg", "type": "Time", "description": "Number of messages in a multiprocessing batch after the message transformation"}, "arroyo.strategies.run_task_with_multiprocessing.output_batch.size.bytes": {"name": "arroyo.strategies.run_task_with_multiprocessing.output_batch.size.bytes", "type": "Time", "description": "Number of bytes in a multiprocessing batch after the message transformation"}, "arroyo.consumer.run.count": {"name": "arroyo.consumer.run.count", "type": "Counter", "description": "Number of times the consumer is spinning"}, "arroyo.consumer.invalid_message.count": {"name": "arroyo.consumer.invalid_message.count", "type": "Counter", "description": "Number of times the consumer encountered an invalid message."}, "arroyo.strategies.reduce.batch_time": {"name": "arroyo.strategies.reduce.batch_time", "type": "Time", "description": "How long it took the Reduce step to fill up a batch"}, "arroyo.strategies.run_task_with_multiprocessing.batch.backpressure": {"name": "arroyo.strategies.run_task_with_multiprocessing.batch.backpressure", "type": "Counter", "description": "Incremented when a strategy after multiprocessing applies\nbackpressure to multiprocessing. May be a reason why CPU cannot be\nsaturated."}, "arroyo.strategies.run_task_with_multiprocessing.batch.input.overflow": {"name": "arroyo.strategies.run_task_with_multiprocessing.batch.input.overflow", "type": "Counter", "description": "Incremented when multiprocessing cannot fill the input batch\nbecause not enough memory was allocated. This results in batches smaller\nthan configured. Increase `input_block_size` to fix."}, "arroyo.strategies.run_task_with_multiprocessing.batch.output.overflow": {"name": "arroyo.strategies.run_task_with_multiprocessing.batch.output.overflow", "type": "Counter", "description": "Incremented when multiprocessing cannot pull results in batches\nequal to the input batch size, because not enough memory was allocated.\nThis can be devastating for throughput. Increase `output_block_size` to\nfix."}, "arroyo.strategies.run_task_with_multiprocessing.batch.input.resize": {"name": "arroyo.strategies.run_task_with_multiprocessing.batch.input.resize", "type": "Counter", "description": "Arroyo has decided to re-allocate a block in order to combat input\nbuffer overflow. This behavior can be disabled by explicitly setting\n`input_block_size` to a not-None value in `RunTaskWithMultiprocessing`."}, "arroyo.strategies.run_task_with_multiprocessing.batch.output.resize": {"name": "arroyo.strategies.run_task_with_multiprocessing.batch.output.resize", "type": "Counter", "description": "Arroyo has decided to re-allocate a block in order to combat output\nbuffer overflow. This behavior can be disabled by explicitly setting\n`output_block_size` to a not-None value in `RunTaskWithMultiprocessing`."}, "arroyo.strategies.run_task_with_multiprocessing.batches_in_progress": {"name": "arroyo.strategies.run_task_with_multiprocessing.batches_in_progress", "type": "Gauge", "description": "How many batches are being processed in parallel by multiprocessing."}, "arroyo.strategies.run_task_with_multiprocessing.processes": {"name": "arroyo.strategies.run_task_with_multiprocessing.processes", "type": "Counter", "description": "A subprocess by multiprocessing unexpectedly died.\n\"sigchld.detected\",\nGauge: Shows how many processes the multiprocessing strategy is\nconfigured with."}, "arroyo.strategies.run_task_with_multiprocessing.pool.create": {"name": "arroyo.strategies.run_task_with_multiprocessing.pool.create", "type": "Counter", "description": "Incremented when the multiprocessing pool is created (or re-created)."}, "arroyo.consumer.poll.time": {"name": "arroyo.consumer.poll.time", "type": "Time", "description": "(unitless) spent polling librdkafka for new messages."}, "arroyo.consumer.processing.time": {"name": "arroyo.consumer.processing.time", "type": "Time", "description": "(unitless) spent in strategies (blocking in strategy.submit or\nstrategy.poll)"}, "arroyo.consumer.backpressure.time": {"name": "arroyo.consumer.backpressure.time", "type": "Time", "description": "(unitless) spent pausing the consumer due to backpressure (MessageRejected)"}, "arroyo.consumer.dlq.time": {"name": "arroyo.consumer.dlq.time", "type": "Time", "description": "(unitless) spent in handling `InvalidMessage` exceptions and sending\nmessages to the the DLQ."}, "arroyo.consumer.join.time": {"name": "arroyo.consumer.join.time", "type": "Time", "description": "(unitless) spent in waiting for the strategy to exit, such as during\nshutdown or rebalancing."}, "arroyo.consumer.callback.time": {"name": "arroyo.consumer.callback.time", "type": "Time", "description": "(unitless) spent in librdkafka callbacks. This metric's timings\noverlap other timings, and might spike at the same time."}, "arroyo.consumer.shutdown.time": {"name": "arroyo.consumer.shutdown.time", "type": "Time", "description": "(unitless) spent in shutting down the consumer. This metric's\ntimings overlap other timings, and might spike at the same time."}, "arroyo.consumer.run.callback": {"name": "arroyo.consumer.run.callback", "type": "Time", "description": "A regular duration metric where each datapoint is measuring the time it\ntook to execute a single callback. This metric is distinct from the\narroyo.consumer.*.time metrics as it does not attempt to accumulate time\nspent per second in an attempt to keep monitoring overhead low.\nThe metric is tagged by the name of the internal callback function being\nexecuted, as 'callback_name'. Possible values are on_partitions_assigned\nand on_partitions_revoked."}, "arroyo.consumer.run.close_strategy": {"name": "arroyo.consumer.run.close_strategy", "type": "Time", "description": "Duration metric measuring the time it took to flush in-flight messages\nand shut down the strategies."}, "arroyo.consumer.run.create_strategy": {"name": "arroyo.consumer.run.create_strategy", "type": "Time", "description": "Duration metric measuring the time it took to create the processing strategy."}, "arroyo.consumer.partitions_revoked.count": {"name": "arroyo.consumer.partitions_revoked.count", "type": "Counter", "description": "How many partitions have been revoked just now."}, "arroyo.consumer.partitions_assigned.count": {"name": "arroyo.consumer.partitions_assigned.count", "type": "Counter", "description": "How many partitions have been assigned just now."}, "arroyo.consumer.latency": {"name": "arroyo.consumer.latency", "type": "Time", "description": "Consumer latency in seconds. Recorded by the commit offsets strategy."}, "arroyo.consumer.pause": {"name": "arroyo.consumer.pause", "type": "Counter", "description": "Metric for when the underlying rdkafka consumer is being paused.\nThis flushes internal prefetch buffers."}, "arroyo.consumer.resume": {"name": "arroyo.consumer.resume", "type": "Counter", "description": "Metric for when the underlying rdkafka consumer is being resumed.\nThis might cause increased network usage as messages are being re-fetched."}, "arroyo.consumer.librdkafka.total_queue_size": {"name": "arroyo.consumer.librdkafka.total_queue_size", "type": "Gauge", "description": "Queue size of background queue that librdkafka uses to prefetch messages."}, "arroyo.processing.strategies.healthcheck.touch": {"name": "arroyo.processing.strategies.healthcheck.touch", "type": "Counter", "description": "Counter metric to measure how often the healthcheck file has been touched."}, "arroyo.strategies.filter.dropped_messages": {"name": "arroyo.strategies.filter.dropped_messages", "type": "Counter", "description": "Number of messages dropped in the FilterStep strategy"}, "arroyo.consumer.dlq.dropped_messages": {"name": "arroyo.consumer.dlq.dropped_messages", "type": "Counter", "description": "how many messages are dropped due to errors producing to the dlq"}, "arroyo.consumer.dlq_buffer.len": {"name": "arroyo.consumer.dlq_buffer.len", "type": "Gauge", "description": "Current length of the DLQ buffer deque"}}
@@ -100,5 +100,6 @@ MetricName = Literal[
100
100
  "arroyo.strategies.filter.dropped_messages",
101
101
  # Counter: how many messages are dropped due to errors producing to the dlq
102
102
  "arroyo.consumer.dlq.dropped_messages",
103
-
103
+ # Gauge: Current length of the DLQ buffer deque
104
+ "arroyo.consumer.dlq_buffer.len",
104
105
  ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: sentry-arroyo
3
- Version: 2.19.12
3
+ Version: 2.20.0
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
@@ -1,6 +1,6 @@
1
1
  arroyo/__init__.py,sha256=fcpHZd2P3MxWl6PJJ8n__fM_NRIfiUE8tKN-orv6lb0,187
2
2
  arroyo/commit.py,sha256=oFihWUW8fLsjomWh0o085qIHe9vwVNgoOJC6JQdFM7M,2235
3
- arroyo/dlq.py,sha256=-mSckVjUZ2j1UgRcxsF5App78-5xb25EaW0zmHDMUH4,15662
3
+ arroyo/dlq.py,sha256=xG59xdadezRcQQjy0ocgK5kpaZefENFXaaIK8kyspqw,16212
4
4
  arroyo/errors.py,sha256=IbtoIbz_m5QrxNRBLOxiy-hOfJQTEwNPCyq6yqedJYk,1059
5
5
  arroyo/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  arroyo/types.py,sha256=sLY0x030np4UmbaW5C1KH1se7Z2pjQiPvAe5x2sXf7A,5684
@@ -31,14 +31,14 @@ arroyo/processing/strategies/reduce.py,sha256=xv9bYisgHHyS8fVD1PdGi4TJsaK-4RAhME
31
31
  arroyo/processing/strategies/run_task.py,sha256=MGe2UcIWN7FkPc9plKzRVUNbZ7Sk0jWjw1z2vVOFI_I,2160
32
32
  arroyo/processing/strategies/run_task_in_threads.py,sha256=f1sb2AG-BLz11X78jfhtERIkdFogrV8vtdT3pyJdkx0,6144
33
33
  arroyo/processing/strategies/run_task_with_multiprocessing.py,sha256=jNb_e3hcXDlnLE0XCgVjbLHXrob8V53aPGeMWtu4ToI,34417
34
- arroyo/processing/strategies/unfold.py,sha256=wZDNdMo1Ln27P1tUvLO2svhL-JDs2ZCyIFF2cq0DxVQ,3400
34
+ arroyo/processing/strategies/unfold.py,sha256=8sMEXReS0Pc-8MpHF_qiRUmiPfF2vaNe5_PGreF-3-Q,4230
35
35
  arroyo/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
36
36
  arroyo/utils/clock.py,sha256=r2EMO4nL5qIb1xnAd1sTAk2yK1UltyUi04lk5BqWKIc,944
37
37
  arroyo/utils/codecs.py,sha256=x-8SJK0GLTOH4c_k24K97JPjBckxyQJcSpgoEViGUy0,541
38
38
  arroyo/utils/concurrent.py,sha256=dbdPinjqmxCQ7izUGFNbGjB3OxfSIO01bnCSTANaVOE,1187
39
39
  arroyo/utils/logging.py,sha256=Y1PnhYcI9XNNEK0H13Ct2xKLr2Niuw0dxayc6sWnui8,606
40
- arroyo/utils/metricDefs.json,sha256=Cpw0IMRy7LqHDm62gQ7enWrpJjX9XbVrnOm9N229ujU,8421
41
- arroyo/utils/metric_defs.py,sha256=oaNPHqOQamRkz5WTnKp58Xud3a8yXHVGiqcsjfDwWf4,6052
40
+ arroyo/utils/metricDefs.json,sha256=Tod5vp5jn1EQbTY2dCTRcsfG1P9E-WpAFaVF6Mv0L54,8573
41
+ arroyo/utils/metric_defs.py,sha256=_swCpX8GuWVX9Wnlo2bCTdknrlHk0GVO2ELa67OBUS8,6141
42
42
  arroyo/utils/metrics.py,sha256=Y6FWlt6bEm_gaIMww3UXKx2w2vXn2tPzrVSeOQ2EKrM,3300
43
43
  arroyo/utils/profiler.py,sha256=aiYy2RRPX_IiDIO7AnFM3hARaHCctS3rqUS5nrHXbSg,2452
44
44
  arroyo/utils/retries.py,sha256=4MRhHUR7da9x1ytlo7YETo8S9HEebXmPF2-mKP4xYz0,3445
@@ -66,13 +66,13 @@ tests/processing/strategies/test_reduce.py,sha256=crPFtGp7cyD8QOsmfVsyYh8KLOTzb8
66
66
  tests/processing/strategies/test_run_task.py,sha256=bWIy4U6QyOBtqdiJdGLMAadlEME-W2aE_ZzDbU_BsGo,2805
67
67
  tests/processing/strategies/test_run_task_in_threads.py,sha256=5nwzF1iV6MTK1xETzWvMEOwAcZWrMOQaIPSWbiAjKFo,1457
68
68
  tests/processing/strategies/test_run_task_with_multiprocessing.py,sha256=iy4etaU9WLa8AfMIFUXRnS70Dj7jlpotIX7s-BhTWH0,21914
69
- tests/processing/strategies/test_unfold.py,sha256=Qic2Y2Un9EYBiW6E84YRvpyNctDNbfh4Ze_-u_nqSus,1633
69
+ tests/processing/strategies/test_unfold.py,sha256=iPXVTyLgqOFhqHXFp3Yq99Mutmh6dg0m9J2VA8npV_w,1788
70
70
  tests/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
71
71
  tests/utils/test_concurrent.py,sha256=Gwdzym2UZ1HO3rhOSGmzxImWcLFygY8P7MXHT3Q0xTE,455
72
72
  tests/utils/test_metrics.py,sha256=bI0EtGgPokMQyEqX58i0-8zvLfxRP2nWaWr2wLMaJ_o,917
73
73
  tests/utils/test_retries.py,sha256=AxJLkXWeL9AjHv_p1n0pe8CXXJp24ZQIuYBHfNcmiz4,3075
74
- sentry_arroyo-2.19.12.dist-info/LICENSE,sha256=0Ng3MFdEcnz0sVD1XvGBBzbavvNp_7OAM5yVObB46jU,10829
75
- sentry_arroyo-2.19.12.dist-info/METADATA,sha256=MiaABmInf8ygaqtrbVKQ85p4TK2biSQIXJqssVD1s_c,2179
76
- sentry_arroyo-2.19.12.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
77
- sentry_arroyo-2.19.12.dist-info/top_level.txt,sha256=DVdMZKysL_iIxm5aY0sYgZtP5ZXMg9YBaBmGQHVmDXA,22
78
- sentry_arroyo-2.19.12.dist-info/RECORD,,
74
+ sentry_arroyo-2.20.0.dist-info/LICENSE,sha256=0Ng3MFdEcnz0sVD1XvGBBzbavvNp_7OAM5yVObB46jU,10829
75
+ sentry_arroyo-2.20.0.dist-info/METADATA,sha256=3gLtABSUjjIShAA260wFKnzvargcr3MYdsViXQiICYI,2178
76
+ sentry_arroyo-2.20.0.dist-info/WHEEL,sha256=beeZ86-EfXScwlR_HKu4SllMC9wUEj_8Z_4FJ3egI2w,91
77
+ sentry_arroyo-2.20.0.dist-info/top_level.txt,sha256=DVdMZKysL_iIxm5aY0sYgZtP5ZXMg9YBaBmGQHVmDXA,22
78
+ sentry_arroyo-2.20.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.0)
2
+ Generator: setuptools (76.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -11,7 +11,7 @@ NOW = datetime.now()
11
11
 
12
12
 
13
13
  def generator(num: int) -> Sequence[Value[int]]:
14
- return [Value(i, {PARTITION: i}, NOW) for i in range(num)]
14
+ return [Value(i, {}, NOW) for i in range(num)]
15
15
 
16
16
 
17
17
  def test_unfold() -> None:
@@ -23,7 +23,9 @@ def test_unfold() -> None:
23
23
  strategy.submit(message)
24
24
 
25
25
  assert next_step.submit.call_args_list == [
26
- call(Message(Value(0, {PARTITION: 0}, NOW))),
26
+ # first message has no committable since the original message has not fully been processed
27
+ call(Message(Value(0, {}, NOW))),
28
+ # second message is last message from batch, so we can say the original msg was fully processed
27
29
  call(Message(Value(1, {PARTITION: 1}, NOW))),
28
30
  ]
29
31
 
@@ -44,7 +46,7 @@ def test_message_rejected() -> None:
44
46
 
45
47
  # Message doesn't actually go through since it was rejected
46
48
  assert next_step.submit.call_args_list == [
47
- call(Message(Value(0, {PARTITION: 0}, NOW))),
49
+ call(Message(Value(0, {}, NOW))),
48
50
  ]
49
51
 
50
52
  # clear the side effect, both messages should be submitted now
@@ -53,7 +55,7 @@ def test_message_rejected() -> None:
53
55
  strategy.poll()
54
56
 
55
57
  assert next_step.submit.call_args_list == [
56
- call(Message(Value(0, {PARTITION: 0}, NOW))),
58
+ call(Message(Value(0, {}, NOW))),
57
59
  call(Message(Value(1, {PARTITION: 1}, NOW))),
58
60
  ]
59
61