snerdmq 1.0.0
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 +7 -0
- data/.gitignore +13 -0
- data/.snerdata/tasks/tasks.log +1 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +22 -0
- data/README.md +85 -0
- data/Rakefile +9 -0
- data/bin/snerdmq-install +73 -0
- data/lib/snerdmq/queue.rb +161 -0
- data/lib/snerdmq.rb +5 -0
- data/snerdmq.gemspec +25 -0
- metadata +97 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: a66bf4a4c973c7d263b27734aa0daff33fa3f098b7faec5b05c0a10dd6baa773
|
|
4
|
+
data.tar.gz: '02592325c65fe165bb87f20ec34a4b34601f16b677dc9fb15f1942239150a1df'
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 931dbad342f26fa5cbe24542de79cd5f740973a06e2b214be4d4274ba1ebfd5d79921d02db6365df01dcc6f64d3fc2aa4d98ae8d466aaae3945da7c51f9ce52d
|
|
7
|
+
data.tar.gz: 7c636234b92c48b47f9c82f3b6fde858a3fd19be8328935f5bf2067107a88f5f3dc07c5cb72b74def125491b21cbd92aef58a49c3bd9b86296269f482f834ebc
|
data/.gitignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"taskId":"ruby-job-1","retryCount":0,"maxRetries":3,"retryAfterHours":0.0,"retryAfterTime":"2026-08-12T15:48:11.816678Z","taskData":"{\"user_id\":\"ruby_master\",\"message\":\"matz\"}","taskType":"test_ruby_job"}
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
snerdmq (1.0.0)
|
|
5
|
+
|
|
6
|
+
GEM
|
|
7
|
+
remote: https://rubygems.org/
|
|
8
|
+
specs:
|
|
9
|
+
minitest (5.27.0)
|
|
10
|
+
rake (13.4.2)
|
|
11
|
+
|
|
12
|
+
PLATFORMS
|
|
13
|
+
arm64-darwin-24
|
|
14
|
+
|
|
15
|
+
DEPENDENCIES
|
|
16
|
+
bundler (~> 2.0)
|
|
17
|
+
minitest (~> 5.0)
|
|
18
|
+
rake (~> 13.0)
|
|
19
|
+
snerdmq!
|
|
20
|
+
|
|
21
|
+
BUNDLED WITH
|
|
22
|
+
2.4.10
|
data/README.md
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<h1>💎 SnerdMQ Ruby SDK</h1>
|
|
3
|
+
<p>A zero-config, C-speed background job queue for Ruby. Ditch Redis and Sidekiq for lightweight, persistent background jobs.</p>
|
|
4
|
+
|
|
5
|
+
[](https://badge.fury.io/rb/snerdmq)
|
|
6
|
+
</div>
|
|
7
|
+
|
|
8
|
+
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.
|
|
9
|
+
|
|
10
|
+
## ✨ Features
|
|
11
|
+
- **Ditch Sidekiq & Redis**: Gives your Ruby apps persistent state, automatic retries, and dead-letter queues right out of the box with zero external infrastructure.
|
|
12
|
+
- **Zero Rust Required**: Our gem installation script automatically downloads the pre-compiled C-speed Rust binary for your OS.
|
|
13
|
+
- **Thread Safe**: Uses native Ruby `Thread`s and `Mutex` locks to orchestrate I/O without blocking your main event loop.
|
|
14
|
+
|
|
15
|
+
## 📦 Installation
|
|
16
|
+
|
|
17
|
+
Installing the SDK is a simple two-step process:
|
|
18
|
+
|
|
19
|
+
**1. Install the gem:**
|
|
20
|
+
```bash
|
|
21
|
+
gem install snerdmq
|
|
22
|
+
# Or add `gem 'snerdmq'` to your Gemfile
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**2. Download the Rust Engine:**
|
|
26
|
+
Run this script from your terminal immediately after installing the gem. It will fetch the correct highly-optimized SnerdMQ binary for your operating system (macOS/Linux/Windows) and place it securely inside the gem installation directory:
|
|
27
|
+
```bash
|
|
28
|
+
snerdmq-install
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## ⚡ Quickstart
|
|
34
|
+
|
|
35
|
+
Using the SDK is incredibly simple. Initialize the queue, register your handler blocks, and start listening!
|
|
36
|
+
|
|
37
|
+
```ruby
|
|
38
|
+
require 'snerdmq'
|
|
39
|
+
|
|
40
|
+
# 1. Initialize the daemon in the background
|
|
41
|
+
queue = Snerdmq::SnerdQueue.new
|
|
42
|
+
|
|
43
|
+
# 2. Register your background job logic using a standard block
|
|
44
|
+
queue.register_handler("send_email") do |data|
|
|
45
|
+
to = data["to"]
|
|
46
|
+
subject = data["subject"]
|
|
47
|
+
puts "Sending email to #{to} with subject: #{subject}..."
|
|
48
|
+
|
|
49
|
+
# Raise an exception here to automatically trigger SnerdMQ's retry logic!
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# 3. Start the non-blocking Thread listeners
|
|
53
|
+
queue.start_listening
|
|
54
|
+
puts "SnerdMQ Ruby SDK is listening for jobs..."
|
|
55
|
+
|
|
56
|
+
# 4. Enqueue a job from anywhere in your codebase
|
|
57
|
+
queue.enqueue(
|
|
58
|
+
task_id: "email-123",
|
|
59
|
+
task_type: "send_email",
|
|
60
|
+
data: { "to" => "john@wick.com", "subject" => "Continental Update" },
|
|
61
|
+
max_retries: 3,
|
|
62
|
+
retry_after_hours: 0.0
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
# Keep main thread alive
|
|
66
|
+
sleep
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## 🌍 Advanced: Distributed Scaling
|
|
72
|
+
|
|
73
|
+
By default, the SDK spins up the Rust daemon which writes the queue to a local file (`.snerdata/tasks/tasks.log`).
|
|
74
|
+
|
|
75
|
+
If you have multiple Ruby microservices (or Rails instances) running behind a load balancer and want them to share the exact same queue, simply mount a **Shared Network Drive** (like AWS EFS or NFS) to all of your servers and pass the shared path:
|
|
76
|
+
|
|
77
|
+
```ruby
|
|
78
|
+
require 'snerdmq'
|
|
79
|
+
|
|
80
|
+
# All of your Ruby servers point to the exact same shared file!
|
|
81
|
+
# SnerdMQ's native OS file-locking guarantees zero data corruption.
|
|
82
|
+
queue = Snerdmq::SnerdQueue.new(storage_path: "/mnt/aws-efs-shared-drive/snerd_tasks.log")
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
*Built with ❤️ for John Wick tier engineering.*
|
data/Rakefile
ADDED
data/bin/snerdmq-install
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require 'net/http'
|
|
4
|
+
require 'uri'
|
|
5
|
+
require 'fileutils'
|
|
6
|
+
require 'rbconfig'
|
|
7
|
+
|
|
8
|
+
REPO = "greyhands2/snerdmq"
|
|
9
|
+
VERSION = "v0.1.1"
|
|
10
|
+
|
|
11
|
+
# Determine OS and Architecture
|
|
12
|
+
host_os = RbConfig::CONFIG['host_os']
|
|
13
|
+
host_cpu = RbConfig::CONFIG['host_cpu']
|
|
14
|
+
|
|
15
|
+
platform = case host_os
|
|
16
|
+
when /darwin|mac os/
|
|
17
|
+
'macos'
|
|
18
|
+
when /linux/
|
|
19
|
+
'linux'
|
|
20
|
+
when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
|
|
21
|
+
'windows'
|
|
22
|
+
else
|
|
23
|
+
puts "[Snerd] Unsupported OS: #{host_os}"
|
|
24
|
+
exit 1
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
architecture = case host_cpu
|
|
28
|
+
when /x86_64|amd64/
|
|
29
|
+
'x64'
|
|
30
|
+
when /arm64|aarch64/
|
|
31
|
+
'arm64'
|
|
32
|
+
else
|
|
33
|
+
puts "[Snerd] Unsupported Architecture: #{host_cpu}"
|
|
34
|
+
exit 1
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
extension = platform == 'windows' ? '.exe' : ''
|
|
38
|
+
binary_name = "snerdmq-#{platform}-#{architecture}#{extension}"
|
|
39
|
+
|
|
40
|
+
download_url = "https://github.com/#{REPO}/releases/download/#{VERSION}/#{binary_name}"
|
|
41
|
+
|
|
42
|
+
# In Ruby, gems are installed in a global read-only directory.
|
|
43
|
+
# It's best to download the binary into the gem's `bin` directory so it ships alongside the library.
|
|
44
|
+
dest_dir = File.expand_path(__dir__)
|
|
45
|
+
dest_path = File.join(dest_dir, "snerdmq#{extension}")
|
|
46
|
+
|
|
47
|
+
puts "[Snerd] Downloading pre-compiled engine from GitHub: #{binary_name}..."
|
|
48
|
+
|
|
49
|
+
uri = URI.parse(download_url)
|
|
50
|
+
response = Net::HTTP.get_response(uri)
|
|
51
|
+
|
|
52
|
+
if response.is_a?(Net::HTTPRedirection)
|
|
53
|
+
uri = URI.parse(response['location'])
|
|
54
|
+
response = Net::HTTP.get_response(uri)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
if response.code == '404'
|
|
58
|
+
puts "\n[Snerd] WARN: Binary not found at #{download_url}"
|
|
59
|
+
puts "[Snerd] (This is expected if you haven't published a GitHub Release yet)"
|
|
60
|
+
puts "[Snerd] Please provide binary_path manually when initializing SnerdQueue.\n"
|
|
61
|
+
exit 0
|
|
62
|
+
elsif response.code != '200'
|
|
63
|
+
puts "[Snerd] Failed to download binary: HTTP #{response.code}"
|
|
64
|
+
exit 1
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
File.open(dest_path, "wb") do |file|
|
|
68
|
+
file.write(response.body)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
FileUtils.chmod(0755, dest_path)
|
|
72
|
+
|
|
73
|
+
puts "[Snerd] Successfully installed Snerd Engine to #{dest_path}!"
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'thread'
|
|
3
|
+
|
|
4
|
+
module Snerdmq
|
|
5
|
+
class SnerdQueue
|
|
6
|
+
def initialize(binary_path: nil, storage_path: nil)
|
|
7
|
+
@binary_path = binary_path
|
|
8
|
+
@storage_path = storage_path
|
|
9
|
+
|
|
10
|
+
if @binary_path.nil?
|
|
11
|
+
ext = RbConfig::CONFIG['host_os'].match?(/mswin|msys|mingw|cygwin|bccwin|wince|emc/) ? '.exe' : ''
|
|
12
|
+
# Assume the binary was downloaded into the gem's bin/ directory via snerdmq-install
|
|
13
|
+
@binary_path = File.expand_path("../../bin/snerdmq#{ext}", __dir__)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
unless File.exist?(@binary_path)
|
|
17
|
+
raise "[Snerd] Binary not found at #{@binary_path}. Ensure it is compiled or run 'snerdmq-install'."
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
@handlers = {}
|
|
21
|
+
@handlers_mutex = Mutex.new
|
|
22
|
+
|
|
23
|
+
@stdin_mutex = Mutex.new
|
|
24
|
+
@shutting_down = false
|
|
25
|
+
@io = nil
|
|
26
|
+
@listener_thread = nil
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def register_handler(task_type, &block)
|
|
30
|
+
@handlers_mutex.synchronize do
|
|
31
|
+
@handlers[task_type] = block
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
if @io && !@shutting_down
|
|
35
|
+
send_message({
|
|
36
|
+
action: "register",
|
|
37
|
+
task_type: task_type
|
|
38
|
+
})
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def start_listening
|
|
43
|
+
args = []
|
|
44
|
+
args << @storage_path if @storage_path
|
|
45
|
+
|
|
46
|
+
# Open a bidirectional pipe to the Rust daemon
|
|
47
|
+
@io = IO.popen([@binary_path] + args, "r+")
|
|
48
|
+
|
|
49
|
+
# Re-register all existing handlers
|
|
50
|
+
@handlers_mutex.synchronize do
|
|
51
|
+
@handlers.keys.each do |task_type|
|
|
52
|
+
send_message({
|
|
53
|
+
action: "register",
|
|
54
|
+
task_type: task_type
|
|
55
|
+
})
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
@listener_thread = Thread.new do
|
|
60
|
+
listen_to_stdout
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def enqueue(task_id:, task_type:, data:, max_retries: 3, retry_after_hours: 0.0)
|
|
65
|
+
raise "[Snerd] Cannot enqueue task: Queue is not running. Call start_listening first." if @io.nil? || @shutting_down
|
|
66
|
+
|
|
67
|
+
send_message({
|
|
68
|
+
action: "enqueue",
|
|
69
|
+
task_id: task_id,
|
|
70
|
+
task_type: task_type,
|
|
71
|
+
task_data: data.to_json,
|
|
72
|
+
max_retries: max_retries,
|
|
73
|
+
retry_after_hours: retry_after_hours
|
|
74
|
+
})
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def shutdown
|
|
78
|
+
@shutting_down = true
|
|
79
|
+
begin
|
|
80
|
+
Process.kill("TERM", @io.pid) if @io && @io.pid
|
|
81
|
+
rescue Errno::ESRCH, Errno::ECHILD
|
|
82
|
+
# Process already dead
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
@listener_thread.join(2) if @listener_thread
|
|
86
|
+
@io.close if @io && !@io.closed?
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
private
|
|
90
|
+
|
|
91
|
+
def send_message(msg)
|
|
92
|
+
@stdin_mutex.synchronize do
|
|
93
|
+
return if @shutting_down || @io.nil? || @io.closed?
|
|
94
|
+
@io.puts(msg.to_json)
|
|
95
|
+
@io.flush
|
|
96
|
+
end
|
|
97
|
+
rescue Errno::EPIPE
|
|
98
|
+
# Broken pipe if the daemon died unexpectedly
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def listen_to_stdout
|
|
102
|
+
@io.each_line do |line|
|
|
103
|
+
next if line.strip.empty?
|
|
104
|
+
|
|
105
|
+
begin
|
|
106
|
+
msg = JSON.parse(line)
|
|
107
|
+
|
|
108
|
+
if msg["action"] == "execute"
|
|
109
|
+
# Execute in a short-lived thread so we don't block the stdout listener loop
|
|
110
|
+
Thread.new { handle_execute(msg) }
|
|
111
|
+
elsif msg["action"] == "max_retries_reached"
|
|
112
|
+
warn "[Snerd] Dead Letter Queue: Task #{msg['task_id']} (#{msg['task_type']}) permanently failed."
|
|
113
|
+
end
|
|
114
|
+
rescue JSON::ParserError
|
|
115
|
+
# Ignore malformed stdout lines
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
rescue IOError, Errno::EPIPE
|
|
119
|
+
# Normal when shutting down
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def handle_execute(msg)
|
|
123
|
+
task_id = msg["task_id"]
|
|
124
|
+
task_type = msg["task_type"]
|
|
125
|
+
|
|
126
|
+
raw_data = msg["task_data"]
|
|
127
|
+
task_data = raw_data.is_a?(String) ? JSON.parse(raw_data) : raw_data
|
|
128
|
+
|
|
129
|
+
handler = nil
|
|
130
|
+
@handlers_mutex.synchronize do
|
|
131
|
+
handler = @handlers[task_type]
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
unless handler
|
|
135
|
+
send_message({
|
|
136
|
+
action: "result",
|
|
137
|
+
task_id: task_id,
|
|
138
|
+
status: "error",
|
|
139
|
+
error_msg: "No handler registered."
|
|
140
|
+
})
|
|
141
|
+
return
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
begin
|
|
145
|
+
handler.call(task_data)
|
|
146
|
+
send_message({
|
|
147
|
+
action: "result",
|
|
148
|
+
task_id: task_id,
|
|
149
|
+
status: "success"
|
|
150
|
+
})
|
|
151
|
+
rescue => e
|
|
152
|
+
send_message({
|
|
153
|
+
action: "result",
|
|
154
|
+
task_id: task_id,
|
|
155
|
+
status: "error",
|
|
156
|
+
error_msg: e.message
|
|
157
|
+
})
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
data/lib/snerdmq.rb
ADDED
data/snerdmq.gemspec
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
lib = File.expand_path("lib", __dir__)
|
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
3
|
+
|
|
4
|
+
Gem::Specification.new do |spec|
|
|
5
|
+
spec.name = "snerdmq"
|
|
6
|
+
spec.version = "1.0.0"
|
|
7
|
+
spec.authors = ["Greyhands2"]
|
|
8
|
+
spec.email = ["developer@example.com"]
|
|
9
|
+
|
|
10
|
+
spec.summary = "A zero-config, persistent background job queue for Ruby."
|
|
11
|
+
spec.description = "The official Ruby SDK for the SnerdMQ Rust daemon. Execute robust, lightning-fast background jobs without Redis."
|
|
12
|
+
spec.homepage = "https://github.com/greyhands2/snerdmq-ruby"
|
|
13
|
+
spec.license = "MIT"
|
|
14
|
+
|
|
15
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
16
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
17
|
+
end
|
|
18
|
+
spec.bindir = "bin"
|
|
19
|
+
spec.executables = ["snerdmq-install"]
|
|
20
|
+
spec.require_paths = ["lib"]
|
|
21
|
+
|
|
22
|
+
spec.add_development_dependency "bundler", "~> 2.0"
|
|
23
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
|
24
|
+
spec.add_development_dependency "minitest", "~> 5.0"
|
|
25
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: snerdmq
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Greyhands2
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2026-08-12 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: bundler
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '2.0'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '2.0'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: rake
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '13.0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '13.0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: minitest
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '5.0'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '5.0'
|
|
55
|
+
description: The official Ruby SDK for the SnerdMQ Rust daemon. Execute robust, lightning-fast
|
|
56
|
+
background jobs without Redis.
|
|
57
|
+
email:
|
|
58
|
+
- developer@example.com
|
|
59
|
+
executables:
|
|
60
|
+
- snerdmq-install
|
|
61
|
+
extensions: []
|
|
62
|
+
extra_rdoc_files: []
|
|
63
|
+
files:
|
|
64
|
+
- ".gitignore"
|
|
65
|
+
- ".snerdata/tasks/tasks.log"
|
|
66
|
+
- Gemfile
|
|
67
|
+
- Gemfile.lock
|
|
68
|
+
- README.md
|
|
69
|
+
- Rakefile
|
|
70
|
+
- bin/snerdmq-install
|
|
71
|
+
- lib/snerdmq.rb
|
|
72
|
+
- lib/snerdmq/queue.rb
|
|
73
|
+
- snerdmq.gemspec
|
|
74
|
+
homepage: https://github.com/greyhands2/snerdmq-ruby
|
|
75
|
+
licenses:
|
|
76
|
+
- MIT
|
|
77
|
+
metadata: {}
|
|
78
|
+
post_install_message:
|
|
79
|
+
rdoc_options: []
|
|
80
|
+
require_paths:
|
|
81
|
+
- lib
|
|
82
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
83
|
+
requirements:
|
|
84
|
+
- - ">="
|
|
85
|
+
- !ruby/object:Gem::Version
|
|
86
|
+
version: '0'
|
|
87
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
88
|
+
requirements:
|
|
89
|
+
- - ">="
|
|
90
|
+
- !ruby/object:Gem::Version
|
|
91
|
+
version: '0'
|
|
92
|
+
requirements: []
|
|
93
|
+
rubygems_version: 3.4.10
|
|
94
|
+
signing_key:
|
|
95
|
+
specification_version: 4
|
|
96
|
+
summary: A zero-config, persistent background job queue for Ruby.
|
|
97
|
+
test_files: []
|