snerdmq 0.3.2 → 0.3.3
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/README.md +68 -9
- data/snerdmq.gemspec +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: 85e9f934b6976cdbd8c95718707762e2da87e93ea53448a51b3983b40d145f26
|
|
4
|
+
data.tar.gz: 82d99ccce4066f516da45f536e36f8539d569cdf47d1a74442b1557086830243
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b18cee9ae796c2c612d44bea8c6aa0e81725e4a27f7f4001bb4c1d66acafc89ea2766c21e573dedebf45a8689b4b2a60abc885ad0d13a632de4da3d9934e2d5c
|
|
7
|
+
data.tar.gz: 815dc8ba1eb2977aba024af95fba389753a0428d3483c3db438e8ced86fada4666c0375d7d6d4b032a3705ac2f8c9fe30aea5c82d9967adc1260c17cfcf53d86
|
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
<img src="./assets/Designer-9.png" height="120" alt="SnerdMQ Ruby Logo" />
|
|
3
|
-
<h1>💎 SnerdMQ Ruby SDK v0.3.
|
|
3
|
+
<h1>💎 SnerdMQ Ruby SDK v0.3.3</h1>
|
|
4
4
|
<p>A zero-config, C-speed background job queue for Ruby. Ditch Redis and Sidekiq for lightweight, persistent background jobs.</p>
|
|
5
5
|
|
|
6
6
|
[](https://badge.fury.io/rb/snerdmq)
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
This is the official Ruby SDK wrapper for **SnerdMQ**. It handles all JSON-RPC communication and `IO.popen` orchestration so you can write lightning-fast background jobs without managing any external databases like Redis or Postgres.
|
|
11
11
|
|
|
12
|
-
## ✨ v0.3.
|
|
12
|
+
## ✨ v0.3.3 AI Features
|
|
13
13
|
- **Smart API Rate-Limiting**: Natively tracks `rate_limit_group` execution velocity to prevent 429 "Too Many Requests" API errors.
|
|
14
14
|
- **Payload-Hashing Deduplication**: Automatically computes cryptographic hashes to drop duplicate tasks instantly.
|
|
15
15
|
- **Dynamic Float Prioritization**: A native Binary Max-Heap bypasses standard FIFO rules for high urgency tasks.
|
|
@@ -18,7 +18,7 @@ This is the official Ruby SDK wrapper for **SnerdMQ**. It handles all JSON-RPC c
|
|
|
18
18
|
- **Zero Rust Required**: Our gem installation script automatically downloads the pre-compiled C-speed Rust binary for your OS.
|
|
19
19
|
- **Thread Safe**: Uses native Ruby `Thread`s and `Mutex` locks to orchestrate I/O without blocking your main event loop.
|
|
20
20
|
|
|
21
|
-
### ⚙️ Advanced Task Configuration (v0.3.
|
|
21
|
+
### ⚙️ Advanced Task Configuration (v0.3.3)
|
|
22
22
|
To power complex AI workflows, tasks can now be configured with advanced orchestration parameters:
|
|
23
23
|
|
|
24
24
|
* **`auto_dedupe` (`true/false`)**: If set to `true`, the daemon computes a cryptographic hash of the `task_type` and `data`. If an identical payload is currently sitting in the queue pending execution, this new task is silently dropped. Excellent for preventing duplicate generative AI requests from trigger-happy users!
|
|
@@ -167,18 +167,77 @@ end
|
|
|
167
167
|
|
|
168
168
|
---
|
|
169
169
|
|
|
170
|
-
##
|
|
170
|
+
## 🧩 Queue Topology: One Queue or Many?
|
|
171
|
+
|
|
172
|
+
### ✅ Recommended: one queue, all job types (singleton)
|
|
173
|
+
|
|
174
|
+
Each `Snerdmq::SnerdQueue` client spawns its own Rust daemon and **exclusively owns** its storage directory (`.snerdata` by default). The recommended pattern is **one client per application process**: register every job type on it and serve a single shared dashboard:
|
|
175
|
+
|
|
176
|
+
```ruby
|
|
177
|
+
require 'snerdmq'
|
|
178
|
+
|
|
179
|
+
# ONE queue client for the whole app
|
|
180
|
+
queue = Snerdmq::SnerdQueue.new
|
|
181
|
+
|
|
182
|
+
# Job type #1: image processing
|
|
183
|
+
queue.register_handler("process_image") do |data|
|
|
184
|
+
puts "Processing image: #{data['image_id']}"
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# Job type #2: OTP emails — same queue, same daemon
|
|
188
|
+
queue.register_handler("send_otp_email") do |data|
|
|
189
|
+
puts "Sending OTP to: #{data['to']}"
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
queue.start_listening
|
|
193
|
+
|
|
194
|
+
# Both job types flow through the exact same queue
|
|
195
|
+
queue.enqueue(task_id: "img-1", task_type: "process_image", data: { "image_id" => "abc123" }, max_retries: 3, retry_after_hours: 0.5)
|
|
196
|
+
queue.enqueue(task_id: "otp-1", task_type: "send_otp_email", data: { "to" => "john@wick.com" }, max_retries: 3, retry_after_hours: 0.5)
|
|
197
|
+
|
|
198
|
+
# ONE dashboard shows every job type
|
|
199
|
+
queue.start_dashboard(port: 8080)
|
|
200
|
+
```
|
|
171
201
|
|
|
172
|
-
|
|
202
|
+
All job types share everything: the same persistent job log, retry/DLQ pipeline, rate-limit state, stats — and one dashboard at `http://localhost:8080` showing all of them.
|
|
173
203
|
|
|
174
|
-
|
|
204
|
+
### 🚫 Same storage twice = fails fast
|
|
205
|
+
|
|
206
|
+
The daemon takes an **exclusive OS-level lock** on its storage directory at startup. A second client on the same storage fails instead of silently double-executing your jobs:
|
|
207
|
+
|
|
208
|
+
```ruby
|
|
209
|
+
first = Snerdmq::SnerdQueue.new # ✅ owns .snerdata
|
|
210
|
+
second = Snerdmq::SnerdQueue.new # ❌ daemon refuses to start:
|
|
211
|
+
# "Another daemon is already running on storage '.snerdata'"
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
This applies across processes too — with **Puma/Unicorn clustered workers, every worker is a separate process** that spawns its own daemon, so each worker needs its own `storage_path` (or run a single dedicated worker process for jobs).
|
|
215
|
+
|
|
216
|
+
### 🔀 Need multiple queues? Give each one its own storage
|
|
217
|
+
|
|
218
|
+
```ruby
|
|
219
|
+
images = Snerdmq::SnerdQueue.new(storage_path: ".snerdata-images")
|
|
220
|
+
emails = Snerdmq::SnerdQueue.new(storage_path: ".snerdata-emails")
|
|
221
|
+
|
|
222
|
+
images.start_dashboard(port: 8080) # separate dashboards, so separate ports
|
|
223
|
+
emails.start_dashboard(port: 8081)
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Now you have two fully independent engines: separate job logs, separate rate-limit state, separate dashboards. Only split when you actually need isolation (different teams, different retention, independent monitoring) — otherwise the singleton is simpler and recommended.
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## 🌍 Advanced: Distributed Scaling
|
|
231
|
+
|
|
232
|
+
Because the daemon exclusively locks its storage directory, scaling horizontally means **one queue per server**, each with its own storage. Your load balancer routes requests across servers, and every server processes the jobs it enqueued:
|
|
175
233
|
|
|
176
234
|
```ruby
|
|
177
235
|
require 'snerdmq'
|
|
178
236
|
|
|
179
|
-
#
|
|
180
|
-
|
|
181
|
-
queue = Snerdmq::SnerdQueue.new(storage_path: "/mnt/aws-efs-shared-drive/snerd_tasks.log")
|
|
237
|
+
# Each server runs its own daemon on its own storage dir (local disk works fine)
|
|
238
|
+
queue = Snerdmq::SnerdQueue.new(storage_path: "/var/data/snerd") # per-server storage
|
|
182
239
|
```
|
|
183
240
|
|
|
241
|
+
A shared network drive (AWS EFS or NFS) is still a good home for that storage when a single instance needs durable state — e.g. a container that restarts but must keep its queue. Native OS file locking (`flock`) keeps writes safe — no Redis required.
|
|
242
|
+
|
|
184
243
|
*Built with ❤️ for John Wick tier engineering.*
|
data/snerdmq.gemspec
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: snerdmq
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Greyhands2
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-08-
|
|
11
|
+
date: 2026-08-19 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rack
|