async-job-processor-redis 0.2.0 → 0.3.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
- checksums.yaml.gz.sig +0 -0
- data/context/getting-started.md +41 -0
- data/context/index.yaml +16 -0
- data/context/redis-queue.md +19 -0
- data/lib/async/job/processor/redis/delayed_jobs.rb +6 -1
- data/lib/async/job/processor/redis/job_store.rb +1 -1
- data/lib/async/job/processor/redis/processing_list.rb +12 -0
- data/lib/async/job/processor/redis/ready_list.rb +6 -1
- data/lib/async/job/processor/redis/server.rb +27 -0
- data/lib/async/job/processor/redis/version.rb +2 -2
- data/lib/async/job/processor/redis.rb +1 -1
- data/readme.md +4 -0
- data/releases.md +4 -0
- data.tar.gz.sig +0 -0
- metadata +5 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 19f21b96ed37f056471ebbb1935460d1be5a2714b4d1e50f9c82f8587587be8c
|
4
|
+
data.tar.gz: 8e1d7ba47c50236eeeb43e2b1ac38cdeba3cc1812ec028999aae7ccd87c91c66
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a7600f75d5a7a9b5b0f0d93e8896889b80853a92b59cfc02413ea12c9d02034108c27961d4878dffe4dddcb42eafd9d25825b985842f03a6514e5bd90004b3da
|
7
|
+
data.tar.gz: 50fa8c45039c3505aea3f8e3dc6df6a1c442994d5ca4e7eb083d851af7d3bfe9e59a23b74a89e955360bdb6b8d951e14ba226364ebdd78a9f862b40e457a17c8
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# Getting Started
|
2
|
+
|
3
|
+
This guide gives you an overview of the `async-job-processor-redis` gem.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add the gem to your project:
|
8
|
+
|
9
|
+
``` shell
|
10
|
+
$ bundle add async-job-processor-redis
|
11
|
+
```
|
12
|
+
|
13
|
+
## Usage
|
14
|
+
|
15
|
+
Here is a full example of the job queue:
|
16
|
+
|
17
|
+
``` ruby
|
18
|
+
require "async"
|
19
|
+
require "async/job"
|
20
|
+
require "async/job/processor/redis"
|
21
|
+
|
22
|
+
Async do
|
23
|
+
buffer = Async::Job::Buffer.new
|
24
|
+
|
25
|
+
queue = Async::Job::Builder.build(buffer) do
|
26
|
+
dequeue Async::Job::Processor::Redis
|
27
|
+
end
|
28
|
+
|
29
|
+
# Run the server:
|
30
|
+
server = Async{queue.start}
|
31
|
+
|
32
|
+
# Enqueue a job:
|
33
|
+
queue.call({message: "Hello, World!"})
|
34
|
+
|
35
|
+
# Wait for the job to complete:
|
36
|
+
job = buffer.pop
|
37
|
+
pp job: job
|
38
|
+
|
39
|
+
server.stop
|
40
|
+
end
|
41
|
+
```
|
data/context/index.yaml
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# Automatically generated context index for Utopia::Project guides.
|
2
|
+
# Do not edit then files in this directory directly, instead edit the guides and then run `bake utopia:project:agent:context:update`.
|
3
|
+
---
|
4
|
+
description: A asynchronous job queue for Ruby.
|
5
|
+
metadata:
|
6
|
+
documentation_uri: https://socketry.github.io/async-job-processor-redis/
|
7
|
+
source_code_uri: https://github.com/socketry/async-job-processor-redis
|
8
|
+
files:
|
9
|
+
- path: getting-started.md
|
10
|
+
title: Getting Started
|
11
|
+
description: This guide gives you an overview of the `async-job-processor-redis`
|
12
|
+
gem.
|
13
|
+
- path: redis-queue.md
|
14
|
+
title: Redis Queue
|
15
|
+
description: This guide gives a brief overview of the implementation of the Redis
|
16
|
+
queue.
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# Redis Queue
|
2
|
+
|
3
|
+
This guide gives a brief overview of the implementation of the Redis queue.
|
4
|
+
|
5
|
+
## Overview
|
6
|
+
|
7
|
+
The Redis queue plays a pivotal role in facilitating a sophisticated and reliable job queue architecture, designed to handle diverse processing needs with efficiency and resilience. The architecture is thoughtfully split into three distinct components, each serving a critical function in the lifecycle of a job: the ready queue, the delayed queue, and the processing queue.
|
8
|
+
|
9
|
+
## Ready Queue
|
10
|
+
|
11
|
+
The ready queue is where jobs that are immediately available for processing are stored. When a job is submitted and is ready to be executed without any delay, it is placed into this queue. Worker processes constantly listen for new jobs on the ready queue, dequeuing and executing them as soon as they become available. This queue operates on a FIFO (First In, First Out) basis, ensuring that jobs are processed in the order they were received.
|
12
|
+
|
13
|
+
## Delayed Queue
|
14
|
+
|
15
|
+
The delayed queue holds jobs that are not meant to be executed immediately but at a specified future time. This functionality is crucial for tasks that need to be executed at a later stage, such as scheduled notifications or time-dependent processes. Jobs in the delayed queue are sorted according to their execution time. When possible, they are moved to the ready queue to be executed by the next available worker. This transition is managed through Redis's sorted sets, allowing efficient retrieval and management of timed events.
|
16
|
+
|
17
|
+
## Processing Queue
|
18
|
+
|
19
|
+
Once a job is dequeued from the ready queue, it enters the processing queue, signifying that it is currently being executed by a worker. The processing queue is crucial for tracking the progress of jobs and for ensuring that jobs can be retried or recovered in case of worker failure. Each worker emits a heartbeat, and if a worker fails to emit a heartbeat within a specified time, any jobs associated with that worker are automatically moved back to the ready queue for reprocessing.
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2024, by Samuel Williams.
|
4
|
+
# Copyright, 2024-2025, by Samuel Williams.
|
5
5
|
|
6
6
|
module Async
|
7
7
|
module Job
|
@@ -36,6 +36,11 @@ module Async
|
|
36
36
|
@move = @client.script(:load, MOVE)
|
37
37
|
end
|
38
38
|
|
39
|
+
# @returns [Integer] The number of jobs currently in the delayed queue.
|
40
|
+
def size
|
41
|
+
@client.zcard(@key)
|
42
|
+
end
|
43
|
+
|
39
44
|
# Start the background task that moves ready delayed jobs to the ready queue.
|
40
45
|
# @parameter ready_list [ReadyList] The ready list to move jobs to.
|
41
46
|
# @parameter resolution [Integer] The check interval in seconds.
|
@@ -73,6 +73,8 @@ module Async
|
|
73
73
|
@requeue = @client.script(:load, REQUEUE)
|
74
74
|
@retry = @client.script(:load, RETRY)
|
75
75
|
@complete = @client.script(:load, COMPLETE)
|
76
|
+
|
77
|
+
@complete_count = 0
|
76
78
|
end
|
77
79
|
|
78
80
|
# @attribute [String] The base Redis key for this processing list.
|
@@ -81,6 +83,14 @@ module Async
|
|
81
83
|
# @attribute [String] The Redis key for this worker's heartbeat.
|
82
84
|
attr :heartbeat_key
|
83
85
|
|
86
|
+
# @attribute [Integer] The total count of all jobs completed by this worker.
|
87
|
+
attr :complete_count
|
88
|
+
|
89
|
+
# @returns [Integer] The number of jobs currently being processed by this worker.
|
90
|
+
def size
|
91
|
+
@client.llen(@pending_key)
|
92
|
+
end
|
93
|
+
|
84
94
|
# Fetch the next job from the ready queue, moving it to this worker's pending list.
|
85
95
|
# This is a blocking operation that waits until a job is available.
|
86
96
|
# @returns [String, nil] The job ID, or nil if no job is available.
|
@@ -91,6 +101,8 @@ module Async
|
|
91
101
|
# Mark a job as completed, removing it from the pending list and job store.
|
92
102
|
# @parameter id [String] The job ID to complete.
|
93
103
|
def complete(id)
|
104
|
+
@complete_count += 1
|
105
|
+
|
94
106
|
@client.evalsha(@complete, 2, @pending_key, @job_store.key, id)
|
95
107
|
end
|
96
108
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2024, by Samuel Williams.
|
4
|
+
# Copyright, 2024-2025, by Samuel Williams.
|
5
5
|
|
6
6
|
module Async
|
7
7
|
module Job
|
@@ -28,6 +28,11 @@ module Async
|
|
28
28
|
# @attribute [String] The Redis key for this ready list.
|
29
29
|
attr :key
|
30
30
|
|
31
|
+
# @returns [Integer] The number of jobs currently in the ready list.
|
32
|
+
def size
|
33
|
+
@client.llen(@key)
|
34
|
+
end
|
35
|
+
|
31
36
|
# Add a new job to the ready queue.
|
32
37
|
# @parameter job [String] The serialized job data.
|
33
38
|
# @parameter job_store [JobStore] The job store to save the job data.
|
@@ -85,6 +85,21 @@ module Async
|
|
85
85
|
super
|
86
86
|
end
|
87
87
|
|
88
|
+
# Generates a human-readable string representing the current statistics.
|
89
|
+
#
|
90
|
+
# e.g. `R=3.42K D=1.23K P=7/2.34K``
|
91
|
+
#
|
92
|
+
# This can be interpreted as:
|
93
|
+
#
|
94
|
+
# - R: Number of jobs in the ready list
|
95
|
+
# - D: Number of jobs in the delayed queue
|
96
|
+
# - P: Number of jobs currently being processed / total number of completed jobs.
|
97
|
+
#
|
98
|
+
# @returns [String] A string representing the current statistics.
|
99
|
+
def status_string
|
100
|
+
"R=#{format_count(@ready_list.size)} D=#{format_count(@delayed_jobs.size)} P=#{format_count(@processing_list.size)}/#{format_count(@processing_list.complete_count)}"
|
101
|
+
end
|
102
|
+
|
88
103
|
# Submit a new job for processing.
|
89
104
|
# Jobs with a scheduled_at time are queued for delayed processing, while immediate jobs are added to the ready queue.
|
90
105
|
# @parameter job [Hash] The job data to process.
|
@@ -121,6 +136,18 @@ module Async
|
|
121
136
|
ensure
|
122
137
|
@processing_list.retry(_id) if _id
|
123
138
|
end
|
139
|
+
|
140
|
+
private
|
141
|
+
|
142
|
+
def format_count(value)
|
143
|
+
if value > 1_000_000
|
144
|
+
"#{(value/1_000_000.0).round(2)}M"
|
145
|
+
elsif value > 1_000
|
146
|
+
"#{(value/1_000.0).round(2)}K"
|
147
|
+
else
|
148
|
+
value
|
149
|
+
end
|
150
|
+
end
|
124
151
|
end
|
125
152
|
end
|
126
153
|
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
|
-
# Copyright, 2024, by Samuel Williams.
|
4
|
+
# Copyright, 2024-2025, by Samuel Williams.
|
5
5
|
|
6
6
|
module Async
|
7
7
|
module Job
|
8
8
|
module Processor
|
9
9
|
module Redis
|
10
|
-
VERSION = "0.
|
10
|
+
VERSION = "0.3.1"
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
data/readme.md
CHANGED
@@ -16,6 +16,10 @@ Please see the [project documentation](https://socketry.github.io/async-job-proc
|
|
16
16
|
|
17
17
|
Please see the [project releases](https://socketry.github.io/async-job-processor-redis/releases/index) for all releases.
|
18
18
|
|
19
|
+
### v0.3.0
|
20
|
+
|
21
|
+
- Add `Async::Job::Processor::Redis::Server#status_string` method to return a string with the current job counts.
|
22
|
+
|
19
23
|
### v0.2.0
|
20
24
|
|
21
25
|
- Achieve 100% documentation coverage.
|
data/releases.md
CHANGED
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: async-job-processor-redis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
@@ -70,6 +70,9 @@ executables: []
|
|
70
70
|
extensions: []
|
71
71
|
extra_rdoc_files: []
|
72
72
|
files:
|
73
|
+
- context/getting-started.md
|
74
|
+
- context/index.yaml
|
75
|
+
- context/redis-queue.md
|
73
76
|
- lib/async/job/processor/redis.rb
|
74
77
|
- lib/async/job/processor/redis/delayed_jobs.rb
|
75
78
|
- lib/async/job/processor/redis/job_store.rb
|
@@ -99,7 +102,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
99
102
|
- !ruby/object:Gem::Version
|
100
103
|
version: '0'
|
101
104
|
requirements: []
|
102
|
-
rubygems_version: 3.6.
|
105
|
+
rubygems_version: 3.6.9
|
103
106
|
specification_version: 4
|
104
107
|
summary: A asynchronous job queue for Ruby.
|
105
108
|
test_files: []
|
metadata.gz.sig
CHANGED
Binary file
|