prosody 0.6.0-x86_64-linux → 0.7.0-x86_64-linux

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 270bd58a5f0184bfe26ef85b0a12442f58bc95c036d09f0b2caa5e117dc06c9c
4
- data.tar.gz: ec405fbe428a3c282fbbb619643cf477a15f7b095c516253495d1c896d7ca653
3
+ metadata.gz: e83fd7ec6d1127ea7aa5e19d1b44b6381e350bb45cefb6d19667165c635cadd8
4
+ data.tar.gz: 895849e38f9526f56d1b589d9fef1f4159fda6b0c912cb529fe72a71912d07b6
5
5
  SHA512:
6
- metadata.gz: 70fc1084d9eaf1edeb3c202c8d973a3a1da426453a290047317b14751852cb7eacbaa6125ff831c260b6dc28d527eb4454c96166227692b537c32838cf7cf2de
7
- data.tar.gz: a504e6950613bd803b71882c363311844f49d616f8cb6d8a188dd37eaf6d6d1f25699d10dc12870901f20274f82e9172acef61b4931d83e263d2bab4bf801306
6
+ metadata.gz: 78393823487ad77efbcdf2632303b9e7c8cef87ebbe51debdbf4925f25eea92627d4672ee5a291b05d5639be51289dba00d0731267e111f4680bc451d60d6c65
7
+ data.tar.gz: 2acd18dd7651523235f02c43f34a42767db8342c4e19a52f3d0d576f7066da4222be2dcbf4617f43953daf51d9108eda1ae782e27c9fd398dcecb50923ee3895
data/.config/rail.toml CHANGED
@@ -1,5 +1,5 @@
1
1
  [plan.work.ci]
2
- paths = [".config/rail.toml", ".github/**", ".taplo.toml", "Makefile"]
2
+ paths = [".config/rail.toml", ".github/**"]
3
3
  scope = "repository"
4
4
 
5
5
  [plan.work.ruby]
@@ -24,3 +24,7 @@ paths = [
24
24
  "typecheck_negative/**",
25
25
  ]
26
26
  scope = "repository"
27
+
28
+ [plan.work.taplo]
29
+ paths = [".taplo.toml"]
30
+ scope = "repository"
@@ -1,3 +1,3 @@
1
1
  {
2
- ".": "0.6.0"
2
+ ".": "0.7.0"
3
3
  }
data/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.7.0](https://github.com/prosody-events/prosody-rb/compare/prosody/v0.6.1...prosody/v0.7.0) (2026-11-13)
4
+
5
+
6
+ ### Features
7
+
8
+ * **deps:** upgrade prosody to 0.8.0 ([#65](https://github.com/prosody-events/prosody-rb/issues/65)) ([2e2c81f](https://github.com/prosody-events/prosody-rb/commit/2e2c81fa7253e6c4eecbf822897f6ebf3ace13fb))
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * **deps:** upgrade dependencies ([#63](https://github.com/prosody-events/prosody-rb/issues/63)) ([eaca537](https://github.com/prosody-events/prosody-rb/commit/eaca53706bcbd9118fa5dfbb0296b9505bb11a24))
14
+
15
+ ## [0.6.1](https://github.com/prosody-events/prosody-rb/compare/prosody/v0.6.0...prosody/v0.6.1) (2026-10-13)
16
+
17
+
18
+ ### Bug Fixes
19
+
20
+ * **deps:** upgrade prosody to 0.7.1 ([#58](https://github.com/prosody-events/prosody-rb/issues/58)) ([54e0556](https://github.com/prosody-events/prosody-rb/commit/54e0556190290985f5dae16bddb09a0dbf8afdd6))
21
+
3
22
  ## [0.6.0](https://github.com/prosody-events/prosody-rb/compare/prosody/v0.5.1...prosody/v0.6.0) (2026-10-02)
4
23
 
5
24
 
data/CONFIGURATION.md CHANGED
@@ -40,14 +40,17 @@ Set `subsystem` to make this client answer requests. Without it, the client cons
40
40
  | Option / Environment Variable | Description | Default |
41
41
  |-----------------------------------------|------------------------------------------------------|------------------------|
42
42
  | `max_concurrency` / `PROSODY_MAX_CONCURRENCY` | Max messages being processed simultaneously | 32 |
43
- | `max_uncommitted` / `PROSODY_MAX_UNCOMMITTED` | Max queued messages before pausing consumption | 64 |
43
+ | `max_uncommitted` / `PROSODY_MAX_UNCOMMITTED` | Max decoded messages in flight across all partitions; at the limit, partitions stop reading | 64 |
44
44
  | `timeout` / `PROSODY_TIMEOUT` | Cancel handler if it runs longer than this | 80% of stall threshold |
45
- | `commit_interval` / `PROSODY_COMMIT_INTERVAL` | How often to save progress to Kafka | 1s |
45
+ | `commit_interval` / `PROSODY_COMMIT_INTERVAL` | How often to save progress to Kafka | 1s |
46
46
  | `poll_interval` / `PROSODY_POLL_INTERVAL` | How often to fetch new messages from Kafka | 100ms |
47
47
  | `shutdown_timeout` / `PROSODY_SHUTDOWN_TIMEOUT` | Shutdown budget; handlers run freely until cancellation fires near the end of the timeout | 30s |
48
48
  | `stall_threshold` / `PROSODY_STALL_THRESHOLD` | Report unhealthy if no progress for this long | 5m |
49
49
  | `probe_port` / `PROSODY_PROBE_PORT` | HTTP port for health checks; use `false`, `:disabled`, or the environment value `none` to disable | 8000 |
50
- | `statistics_interval` / `PROSODY_STATISTICS_INTERVAL` | How often librdkafka reports client statistics; must be between 1ms and 24h | 5s |
50
+ | `statistics_interval` / `PROSODY_STATISTICS_INTERVAL` | How often librdkafka reports client statistics | 5s |
51
+ | `partition_prefetch` / `PROSODY_PARTITION_PREFETCH` | Bytes of fetched records that wait for each assigned partition; accepts sizes such as `128 KiB`. Fetched memory grows with the number of assigned partitions (about two times this value, plus one batch, per partition) | 128 KiB |
52
+ | `fetch_max_bytes` / `PROSODY_FETCH_MAX_BYTES` | Maximum bytes in one fetch response from one broker; accepts sizes such as `50 MiB` | 50 MiB |
53
+ | `fetch_wait` / `PROSODY_FETCH_WAIT` | How long a broker can hold a fetch request when no new records are available. A shorter wait lowers the delay for a partition that is behind, but an idle consumer sends more fetch requests | 500ms |
51
54
  | `failure_topic` / `PROSODY_FAILURE_TOPIC` | Send unprocessable messages here (dead letter queue) | - |
52
55
  | `idempotence_cache_size` / `PROSODY_IDEMPOTENCE_CACHE_SIZE` | Capacity of the producer idempotence cache and of the consumer deduplication cache. Consumer deduplication cannot be turned off, so the value must be at least 1 | 8192 |
53
56
  | `idempotence_version` / `PROSODY_IDEMPOTENCE_VERSION` | Version string for cache-busting dedup hashes | 1 |
data/README.md CHANGED
@@ -12,7 +12,7 @@ strategies, and integrated OpenTelemetry support for distributed tracing.
12
12
  - **Keyed State**: Per-key value/map/deque collections that survive across events, transactional by default
13
13
  - **Quality of Service**: Fair scheduling limits concurrency and prevents failures from starving fresh traffic. Pipeline mode adds deferred retry and monopolization detection
14
14
  - **Distributed Tracing**: OpenTelemetry integration for tracing message flow across services
15
- - **Backpressure**: Pauses partitions when handlers fall behind
15
+ - **Backpressure**: Stops reading a partition when handlers fall behind
16
16
  - **Mocking**: In-memory Kafka broker for tests (`mock: true`)
17
17
  - **Failure Handling**: Pipeline (retry forever), Low-Latency (dead letter), Best-Effort (log and skip)
18
18
 
@@ -36,6 +36,15 @@ State definitions carry their item types through `context.state`. A bare handler
36
36
  message, definition, or state handle uses `Prosody::json_value`. See the
37
37
  [typed examples](examples/) for Ruby and companion RBS files checked by Steep.
38
38
 
39
+ ### Kafka version
40
+
41
+ Prosody requires Kafka 4.0 or later. Consumers use the broker-side consumer
42
+ group protocol (KIP-848). The broker assigns partitions, and a rebalance
43
+ changes only the members whose partitions move. Brokers older than 4.0 do
44
+ not support this protocol, and the client does not fall back to the classic
45
+ protocol. A consumer that connects to an older broker logs a fatal error and
46
+ gets no partitions, so its readiness probe stays unready.
47
+
39
48
  ## Quick Start
40
49
 
41
50
  ```ruby
@@ -110,7 +119,7 @@ Prosody enables efficient, parallel processing of Kafka messages while maintaini
110
119
  - **Partition-Level Parallelism**: Separate management of each Kafka partition
111
120
  - **Key-Based Queuing**: Ordered processing for each key within a partition
112
121
  - **Concurrent Processing**: Simultaneous processing of different keys
113
- - **Backpressure Management**: Pause consumption from backed-up partitions
122
+ - **Backpressure Management**: Stop reading from backed-up partitions
114
123
 
115
124
  ## Quality of Service
116
125
 
@@ -457,8 +466,10 @@ This prevents endless loops where a service consumes its own produced messages.
457
466
 
458
467
  ## Message Deduplication
459
468
 
460
- Prosody automatically deduplicates messages using the `id` field in their JSON payload. Consecutive messages with the
461
- same ID and key are processed only once.
469
+ Prosody uses the JSON payload's `id` field to detect duplicate messages. For a consumer group and idempotence version,
470
+ messages with the same ID, key, topic, and partition share a deduplication record. Other messages can arrive between duplicates.
471
+ Prosody skips a duplicate while its record remains in the cache or persistent store. Deduplication is best-effort;
472
+ handlers must remain idempotent.
462
473
 
463
474
  The deduplication system uses:
464
475
  - A **global in-memory cache** shared across all partitions, surviving partition reassignments within a process
@@ -625,7 +636,7 @@ State operations look synchronous. They yield the current fiber while Prosody pe
625
636
 
626
637
  | Collection | JSON payload | Kafka message | Main operations |
627
638
  | --- | --- | --- | --- |
628
- | Value | `Prosody.value` | `Prosody.message_value` | `get`, `set`, `clear` |
639
+ | Value | `Prosody.value` | `Prosody.message_value` | `get`, `exist?`, `set`, `clear` |
629
640
  | Ordered string map | `Prosody.map` | `Prosody.message_map` | `get`, `get_many`, `key?`, `contains_many`, `empty?`, `set`, `delete`, `each_pair`, `each_key`, `clear` |
630
641
  | Ordered string set | `Prosody.set` | - | `add` / `<<`, `delete`, `include?`, `contains_many`, `empty?`, `each`, `clear` |
631
642
  | Deque | `Prosody.deque` | `Prosody.message_deque` | `push`, `unshift`, `pop`, `shift`, `get`, `length`, `each`, `clear` |
@@ -1263,7 +1274,7 @@ Definition constructors (each returns a frozen definition object used both in `C
1263
1274
 
1264
1275
  Each constructor returns a `StateDefinition`. It exposes `name`, `kind`, `payload`, all supplied options, and `to_state_config`.
1265
1276
 
1266
- Published readers take the user key as their first argument. `Prosody::PublishedValue` provides `get`.
1277
+ Published readers take the user key as their first argument. `Prosody::PublishedValue` provides `get` and `exist?`.
1267
1278
 
1268
1279
  `Prosody::PublishedMap` provides `get`, `get_many`, `key?`, `has_key?`, `include?`, `member?`, `contains_many`, and `empty?`.
1269
1280
 
@@ -1277,7 +1288,7 @@ Traversal methods return an `Enumerator` without a block. Every traversal accept
1277
1288
 
1278
1289
  `Prosody::ValueState`:
1279
1290
 
1280
- - `get` / `value`, `set(value)` / `value=`, `clear`, `commit`, and `rollback`
1291
+ - `get` / `value`, `exist?`, `set(value)` / `value=`, `clear`, `commit`, and `rollback`
1281
1292
 
1282
1293
  `Prosody::MapState` (keys are `String`):
1283
1294
 
@@ -1,4 +1,4 @@
1
1
  [diffend] Oversized file quarantined before diffing.
2
2
  name: data/lib/prosody/3.2/prosody.so
3
- size: 39097088 bytes
4
- sha256: b58385c6ee712db4a5fbebb2309ece562c59852682f8d2498f6043b3bea77a52
3
+ size: 39980432 bytes
4
+ sha256: 1c34ab1c1de242d3a7674df7da803b12d8da8518976e7c414570d724bbef3c05
@@ -1,4 +1,4 @@
1
1
  [diffend] Oversized file quarantined before diffing.
2
2
  name: data/lib/prosody/3.3/prosody.so
3
- size: 39097088 bytes
4
- sha256: e431827edf8ab1772a94ff5717e8d7211c573191fbe709c99862693783771aa6
3
+ size: 39980432 bytes
4
+ sha256: 3c1202a361806f1dac0ee2d7cf56031f76530b785c0b183b71380785c716075b
@@ -1,4 +1,4 @@
1
1
  [diffend] Oversized file quarantined before diffing.
2
2
  name: data/lib/prosody/3.4/prosody.so
3
- size: 39092992 bytes
4
- sha256: c073e39e77b5551c79fbd4b072e63d5beb119e1e4914e13d621f19ef3f4a353d
3
+ size: 39972240 bytes
4
+ sha256: ec13e9e3383a5cf6a743a1df0239b81ec65c96e9ea18c895b643eba60ae4acc1
@@ -128,6 +128,22 @@ module Prosody
128
128
  # Env: PROSODY_STATISTICS_INTERVAL. Default: 5 seconds.
129
129
  config_param :statistics_interval, converter: ->(v) { duration_converter(v) }
130
130
 
131
+ # Bytes of fetched records that wait for each assigned partition, such as
132
+ # "128 KiB". Fetched memory grows with the number of assigned partitions:
133
+ # about two times this value, plus one batch, per partition.
134
+ # Env: PROSODY_PARTITION_PREFETCH. Default: 128 KiB.
135
+ config_param :partition_prefetch, converter: lambda(&:to_s)
136
+
137
+ # Maximum bytes in one fetch response from one broker, such as "50 MiB".
138
+ # Env: PROSODY_FETCH_MAX_BYTES. Default: 50 MiB.
139
+ config_param :fetch_max_bytes, converter: lambda(&:to_s)
140
+
141
+ # How long a broker can hold a fetch request when no new records are
142
+ # available (in seconds). A shorter wait lowers the delay for a partition
143
+ # that is behind, but an idle consumer sends more fetch requests.
144
+ # Env: PROSODY_FETCH_WAIT. Default: 0.5 seconds.
145
+ config_param :fetch_wait, converter: ->(v) { duration_converter(v) }
146
+
131
147
  # Base delay for retry operations (in seconds).
132
148
  config_param :retry_base, converter: ->(v) { duration_converter(v) }
133
149
 
@@ -16,6 +16,13 @@ module Prosody
16
16
  # @return [Object, nil] the stored value, or `nil` when absent
17
17
  def get = @native.get
18
18
 
19
+ # Returns true when the handle holds a value, including a buffered write.
20
+ # The check does not decode the value. For a message value, it does not
21
+ # fetch the Kafka message.
22
+ #
23
+ # @return [Boolean]
24
+ def exist? = @native.contains
25
+
19
26
  # Buffers a write of the value.
20
27
  #
21
28
  # @param value [Object] the value to store (JSON, or a message)
@@ -54,5 +61,12 @@ module Prosody
54
61
  # @param key [String] the user key
55
62
  # @return [Object, nil] the value, or +nil+ when it is absent
56
63
  def get(key) = @native.get(key)
64
+
65
+ # Returns true when a committed value exists for +key+. The check does not
66
+ # decode the value.
67
+ #
68
+ # @param key [String] the user key
69
+ # @return [Boolean]
70
+ def exist?(key) = @native.contains(key)
57
71
  end
58
72
  end
@@ -6,5 +6,5 @@ module Prosody
6
6
  # This version number follows semantic versioning and is used by the
7
7
  # gem system to identify the library version. It should be updated
8
8
  # according to semver guidelines when making releases.
9
- VERSION = "0.6.0"
9
+ VERSION = "0.7.0"
10
10
  end
@@ -67,6 +67,21 @@ module Prosody
67
67
  def statistics_interval: () -> Float?
68
68
  def statistics_interval=: (Numeric) -> Float
69
69
 
70
+ # Bytes of fetched records that wait for each assigned partition. Accepts
71
+ # a human-readable size. Uses PROSODY_PARTITION_PREFETCH when omitted.
72
+ def partition_prefetch: () -> String?
73
+ def partition_prefetch=: (String | _ToS) -> String
74
+
75
+ # Maximum bytes in one fetch response from one broker. Accepts a
76
+ # human-readable size. Uses PROSODY_FETCH_MAX_BYTES when omitted.
77
+ def fetch_max_bytes: () -> String?
78
+ def fetch_max_bytes=: (String | _ToS) -> String
79
+
80
+ # How long a broker can hold a fetch request when no new records are
81
+ # available (seconds). Uses PROSODY_FETCH_WAIT when omitted.
82
+ def fetch_wait: () -> Float?
83
+ def fetch_wait=: (Numeric) -> Float
84
+
70
85
  # Base delay for retry operations (seconds)
71
86
  def retry_base: () -> Float?
72
87
  def retry_base=: (Numeric) -> Float
data/sig/published.rbs CHANGED
@@ -2,6 +2,7 @@ module Prosody
2
2
  # --- published-state readers, opened by Client#state -------------------
3
3
  class NativePublishedValue
4
4
  def get: (String key) -> json_value?
5
+ def contains: (String key) -> bool
5
6
  end
6
7
 
7
8
  class NativePublishedMap
@@ -32,6 +33,7 @@ module Prosody
32
33
 
33
34
  class PublishedValue[T = json_value]
34
35
  def get: (String key) -> T?
36
+ def exist?: (String key) -> bool
35
37
 
36
38
  private
37
39
  def initialize: (NativePublishedValue native) -> void
data/sig/state.rbs CHANGED
@@ -110,6 +110,7 @@ module Prosody
110
110
  # Every op is fiber-yield async: it looks blocking but never blocks the thread.
111
111
  class ValueState[T = json_value] < State::Handle
112
112
  def get: () -> T?
113
+ def exist?: () -> bool
113
114
  def set: (T value) -> void
114
115
  def clear: () -> void
115
116
 
@@ -230,6 +231,7 @@ module Prosody
230
231
 
231
232
  interface _NativeValueHandle[T]
232
233
  def get: () -> T?
234
+ def contains: () -> bool
233
235
  def set: (T value) -> void
234
236
  def clear: () -> void
235
237
  def commit: () -> store_outcome
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prosody
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: x86_64-linux
6
6
  authors:
7
7
  - Joshua Griffith
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-10-02 00:00:00.000000000 Z
11
+ date: 2026-11-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async
@@ -86,14 +86,14 @@ dependencies:
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '7.0'
89
+ version: '7.2'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '7.0'
96
+ version: '7.2'
97
97
  description: |
98
98
  Prosody offers Ruby bindings to the Prosody Kafka client, providing features
99
99
  for message production and consumption, including configurable retry