event_people 1.2.0 → 1.2.1
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 +4 -4
- data/.event_people.yml +2 -2
- data/README.md +59 -0
- data/lib/event_people/broker/rabbit/rabbit_context.rb +10 -5
- data/lib/event_people/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c7f60b5a8806b69e26b0f66ea3a547e92200f460df4f30a2df90eed2fa08641d
|
|
4
|
+
data.tar.gz: 343c7a4e19f4a0194e552b507f3d000a1fd723faf374a35faee8961527c1809f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dbd234e3c4df60f769feb130c05b8d96421677e8e297704b5620f41749ba3a507bfae2d22af9c020612d5fbb2b1f426bc427b8e71f476235de68a1fb806e1e38
|
|
7
|
+
data.tar.gz: 791f1ee04535ed6eef1d3fd9cb5771da399b336b946d9b4fef7f46b43d362781c6698a26aafac727620ef792f93a2f8fab6f2e59f3460655073c8a2937ab8600
|
data/.event_people.yml
CHANGED
data/README.md
CHANGED
|
@@ -220,6 +220,65 @@ EventPeople::Daemon.start
|
|
|
220
220
|
```
|
|
221
221
|
[See more details](https://github.com/pin-people/event_people_ruby/blob/master/examples/daemon.rb)
|
|
222
222
|
|
|
223
|
+
## Retry and Dead Letter Queue (DLQ)
|
|
224
|
+
|
|
225
|
+
### Environment variables
|
|
226
|
+
|
|
227
|
+
| Variable | Description | Default |
|
|
228
|
+
|---|---|---|
|
|
229
|
+
| `RABBIT_EVENT_PEOPLE_MAX_RETRIES` | Max retry attempts before dead-lettering | `3` |
|
|
230
|
+
| `RABBIT_EVENT_PEOPLE_RETRY_TTL_MS` | Base delay in ms for retry backoff | `1000` |
|
|
231
|
+
|
|
232
|
+
### How it works
|
|
233
|
+
|
|
234
|
+
On `context.fail`:
|
|
235
|
+
- If retries remain → message published to `{queue}_retry` with exponential backoff delay, then acked
|
|
236
|
+
- If retries exhausted → nacked to DLQ via RabbitMQ DLX
|
|
237
|
+
|
|
238
|
+
On `context.reject` → nacked directly to DLQ (no retries)
|
|
239
|
+
|
|
240
|
+
**Delay strategies:**
|
|
241
|
+
- `exponential` (default): `min(initialDelay × 5^retry_count, 600000)` ms
|
|
242
|
+
- `fixed`: constant `initialDelay` ms
|
|
243
|
+
|
|
244
|
+
### Queue topology (auto-created on subscribe)
|
|
245
|
+
|
|
246
|
+
| Queue/Exchange | Name | Purpose |
|
|
247
|
+
|---|---|---|
|
|
248
|
+
| Exchange (DLX) | `{app_name}_dlx` | Fanout, receives dead-lettered messages |
|
|
249
|
+
| DLQ | `{app_name}_dlq` | Final resting place for failed messages |
|
|
250
|
+
| Retry queue | `{queue_name}_retry` | Holds messages until backoff delay expires |
|
|
251
|
+
|
|
252
|
+
### Usage
|
|
253
|
+
|
|
254
|
+
```ruby
|
|
255
|
+
class OrderListener < EventPeople::Listeners::Base
|
|
256
|
+
bind :handle_created, 'order.service.created'
|
|
257
|
+
|
|
258
|
+
def handle_created(event)
|
|
259
|
+
puts "Attempt #{event.retry_count + 1} of #{context.max_retries}"
|
|
260
|
+
|
|
261
|
+
if invalid?(event)
|
|
262
|
+
reject # → DLQ immediately, no retries
|
|
263
|
+
return
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
process(event)
|
|
267
|
+
success
|
|
268
|
+
rescue StandardError
|
|
269
|
+
puts 'Final attempt, sending to DLQ' if context.is_last_retry
|
|
270
|
+
fail # → retry queue (or DLQ if exhausted)
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
# Per-listener retry config (overrides env var defaults)
|
|
275
|
+
EventPeople::Listener.on('order.service.created', method(:handle),
|
|
276
|
+
max_attempts: 5,
|
|
277
|
+
delay_strategy: 'exponential')
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
> **Note:** `success!`, `fail!`, `reject!` still work but are deprecated — prefer `success`, `fail`, `reject`.
|
|
281
|
+
|
|
223
282
|
## Development
|
|
224
283
|
|
|
225
284
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
@@ -34,18 +34,23 @@ module EventPeople
|
|
|
34
34
|
expiration: delay.to_s,
|
|
35
35
|
headers: { 'x-event-people-retries' => @retry_count + 1 }
|
|
36
36
|
)
|
|
37
|
-
@channel.ack(@delivery_info.delivery_tag, false)
|
|
38
37
|
rescue => e
|
|
39
|
-
#
|
|
40
|
-
#
|
|
41
|
-
# AMQP at-least-once limitation. We prefer redelivery over silent loss.
|
|
38
|
+
# Publish failed — nack without requeue so the DLX routes to DLQ.
|
|
39
|
+
# Requeuing without incrementing x-event-people-retries would cause an infinite loop.
|
|
42
40
|
begin
|
|
43
|
-
@channel.nack(@delivery_info.delivery_tag, false,
|
|
41
|
+
@channel.nack(@delivery_info.delivery_tag, false, false)
|
|
44
42
|
rescue
|
|
45
43
|
# Channel may already be closed; nothing we can do.
|
|
46
44
|
end
|
|
47
45
|
raise e
|
|
48
46
|
end
|
|
47
|
+
begin
|
|
48
|
+
@channel.ack(@delivery_info.delivery_tag, false)
|
|
49
|
+
rescue
|
|
50
|
+
# Publish already succeeded; swallow ack errors. The message may be redelivered
|
|
51
|
+
# once (at-least-once), but that is safer than nacking to DLQ when a retry copy
|
|
52
|
+
# is already enqueued.
|
|
53
|
+
end
|
|
49
54
|
else
|
|
50
55
|
@channel.nack(@delivery_info.delivery_tag, false, false)
|
|
51
56
|
end
|
data/lib/event_people/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: event_people
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.2.
|
|
4
|
+
version: 1.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Pin People
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-06-
|
|
11
|
+
date: 2026-06-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|