async-job 0.10.0 → 0.10.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/lib/async/job/buffer.rb +17 -2
- data/lib/async/job/builder.rb +26 -2
- data/lib/async/job/coder/marshal.rb +13 -2
- data/lib/async/job/coder/message_pack.rb +15 -2
- data/lib/async/job/coder.rb +7 -3
- data/lib/async/job/generic.rb +18 -0
- data/lib/async/job/processor/aggregate.rb +20 -7
- data/lib/async/job/processor/delayed.rb +11 -4
- data/lib/async/job/processor/generic.rb +10 -1
- data/lib/async/job/processor/inline.rb +18 -6
- data/lib/async/job/processor.rb +9 -2
- data/lib/async/job/queue.rb +16 -0
- data/lib/async/job/version.rb +1 -1
- data/lib/async/job.rb +13 -5
- data/license.md +2 -1
- data/readme.md +64 -0
- data/releases.md +114 -0
- data.tar.gz.sig +0 -0
- metadata +6 -10
- 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: d1c3279d12ab740fa116707c840e5003adf0046f3c6d61b2d91e29f60c0e1429
|
4
|
+
data.tar.gz: 34751f4aadfcf4183f8123cc5396ff646be312a43e864833543a70187c94fd6f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 88c3693057b6c972fc18922291fb8174be094edc639f44c41d6dca40b1e209e4dc78601859cef68c5a58776ea65b7a5af3003491d5bbf97cf5dfe345c5337bce
|
7
|
+
data.tar.gz: 8ecbe70b32f7ead852d046e39cafd9acee5ad0e2e0edecd2dedeff4bd25b44101d0801f9f5a6a3f97cc2c89a3f6c6b43f6ce3f820ecd880941708f5d697ac3e6
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/lib/async/job/buffer.rb
CHANGED
@@ -1,37 +1,52 @@
|
|
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
|
+
# Copyright, 2025, by Shopify Inc.
|
5
6
|
|
6
|
-
require
|
7
|
+
require "async/queue"
|
7
8
|
|
8
9
|
module Async
|
9
10
|
module Job
|
11
|
+
# Represents a job buffer that stores and manages job execution.
|
12
|
+
# The buffer acts as an intermediary between job producers and consumers,
|
13
|
+
# providing a thread-safe queue for job storage and optional delegation.
|
10
14
|
class Buffer
|
15
|
+
# Initialize a new job buffer.
|
16
|
+
# @parameter delegate [Object | nil] An optional delegate object that will receive job events.
|
11
17
|
def initialize(delegate = nil)
|
12
18
|
@jobs = Async::Queue.new
|
13
19
|
@delegate = delegate
|
14
20
|
end
|
15
21
|
|
22
|
+
# Check if the buffer contains any pending jobs.
|
23
|
+
# @returns [Boolean] True if the buffer is empty, false otherwise.
|
16
24
|
def empty?
|
17
25
|
@jobs.empty?
|
18
26
|
end
|
19
27
|
|
28
|
+
# @attribute [Async::Queue] The internal queue containing pending jobs.
|
20
29
|
attr :jobs
|
21
30
|
|
31
|
+
# Add a job to the buffer and optionally delegate to the configured delegate.
|
32
|
+
# @parameter job [Object] The job to be added to the buffer.
|
22
33
|
def call(job)
|
23
34
|
@jobs.enqueue(job)
|
24
35
|
@delegate&.call(job)
|
25
36
|
end
|
26
37
|
|
38
|
+
# Remove and return the next job from the buffer.
|
39
|
+
# @returns [Object | nil] The next job from the buffer, or nil if empty.
|
27
40
|
def pop
|
28
41
|
@jobs.dequeue
|
29
42
|
end
|
30
43
|
|
44
|
+
# Start the buffer's delegate if one is configured.
|
31
45
|
def start
|
32
46
|
@delegate&.start
|
33
47
|
end
|
34
48
|
|
49
|
+
# Stop the buffer's delegate if one is configured.
|
35
50
|
def stop
|
36
51
|
@delegate&.stop
|
37
52
|
end
|
data/lib/async/job/builder.rb
CHANGED
@@ -1,13 +1,21 @@
|
|
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
|
+
# Copyright, 2025, by Shopify Inc.
|
5
6
|
|
6
|
-
require_relative
|
7
|
+
require_relative "queue"
|
7
8
|
|
8
9
|
module Async
|
9
10
|
module Job
|
11
|
+
# Represents a builder for creating job processing pipelines.
|
12
|
+
# The builder allows you to configure middleware for both enqueue and dequeue operations,
|
13
|
+
# creating a complete job processing system with client and server components.
|
10
14
|
class Builder
|
15
|
+
# Build a job processing pipeline using the provided delegate and configuration block.
|
16
|
+
# @parameter delegate [Object | nil] The delegate that will execute the jobs.
|
17
|
+
# @yields {|builder| ...} The builder instance for configuration.
|
18
|
+
# @returns [Async::Job::Queue] A configured job queue with client and server components.
|
11
19
|
def self.build(delegate = nil, &block)
|
12
20
|
builder = self.new(delegate)
|
13
21
|
|
@@ -16,6 +24,7 @@ module Async
|
|
16
24
|
return builder.build
|
17
25
|
end
|
18
26
|
|
27
|
+
# Initialize a new job builder.
|
19
28
|
# @parameter delegate [Object] The initial delegate that will be wrapped by the queue.
|
20
29
|
def initialize(delegate = nil)
|
21
30
|
# The client side middleware, in the order they should be applied to a job:
|
@@ -28,18 +37,33 @@ module Async
|
|
28
37
|
@delegate = delegate
|
29
38
|
end
|
30
39
|
|
40
|
+
# Add middleware to the enqueue pipeline.
|
41
|
+
# @parameter middleware [Class] The middleware class to add.
|
31
42
|
def enqueue(middleware, ...)
|
32
43
|
@enqueue << ->(delegate){middleware.new(delegate, ...)}
|
44
|
+
|
45
|
+
return self
|
33
46
|
end
|
34
47
|
|
48
|
+
# Add middleware to the dequeue pipeline.
|
49
|
+
# @parameter middleware [Class] The middleware class to add.
|
35
50
|
def dequeue(middleware, ...)
|
36
51
|
@dequeue << ->(delegate){middleware.new(delegate, ...)}
|
52
|
+
|
53
|
+
return self
|
37
54
|
end
|
38
55
|
|
56
|
+
# Set the delegate that will execute the jobs.
|
57
|
+
# @parameter delegate [Object] The delegate object.
|
39
58
|
def delegate(delegate)
|
40
59
|
@delegate = delegate
|
60
|
+
|
61
|
+
return self
|
41
62
|
end
|
42
63
|
|
64
|
+
# Build the final job processing pipeline.
|
65
|
+
# @parameter delegate [Object] The delegate to use (defaults to the instance delegate).
|
66
|
+
# @returns [Async::Job::Queue] A configured job queue.
|
43
67
|
def build(delegate = @delegate)
|
44
68
|
# We then wrap the delegate with the middleware in reverse order:
|
45
69
|
@dequeue.reverse_each do |middleware|
|
@@ -1,22 +1,33 @@
|
|
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
|
+
# Copyright, 2025, by Shopify Inc.
|
5
6
|
|
6
|
-
require
|
7
|
+
require "msgpack"
|
7
8
|
|
8
9
|
module Async
|
9
10
|
module Job
|
10
11
|
module Coder
|
12
|
+
# Represents a coder that uses Ruby's Marshal for job serialization.
|
13
|
+
# Marshal provides fast serialization but is Ruby-specific and not suitable
|
14
|
+
# for cross-language job processing systems.
|
11
15
|
class Marshal
|
16
|
+
# Serialize a job object using Ruby's Marshal.
|
17
|
+
# @parameter job [Object] The job object to serialize.
|
18
|
+
# @returns [String] The serialized job data.
|
12
19
|
def dump(job)
|
13
20
|
::Marshal.dump(job)
|
14
21
|
end
|
15
22
|
|
23
|
+
# Deserialize job data using Ruby's Marshal.
|
24
|
+
# @parameter data [String] The serialized job data.
|
25
|
+
# @returns [Object] The deserialized job object.
|
16
26
|
def load(data)
|
17
27
|
::Marshal.load(data)
|
18
28
|
end
|
19
29
|
|
30
|
+
# @attribute [Async::Job::Coder::Marshal] The default Marshal coder instance.
|
20
31
|
DEFAULT = self.new
|
21
32
|
end
|
22
33
|
end
|
@@ -1,14 +1,20 @@
|
|
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
|
+
# Copyright, 2025, by Shopify Inc.
|
5
6
|
|
6
|
-
require
|
7
|
+
require "msgpack"
|
7
8
|
|
8
9
|
module Async
|
9
10
|
module Job
|
10
11
|
module Coder
|
12
|
+
# Represents a coder that uses MessagePack for job serialization.
|
13
|
+
# MessagePack provides fast, compact serialization that is language-agnostic,
|
14
|
+
# making it suitable for cross-language job processing systems.
|
11
15
|
class MessagePack
|
16
|
+
# Initialize a new MessagePack coder with custom type registrations.
|
17
|
+
# Registers Symbol and Time types for proper serialization.
|
12
18
|
def initialize
|
13
19
|
@factory = ::MessagePack::Factory.new
|
14
20
|
|
@@ -20,14 +26,21 @@ module Async
|
|
20
26
|
)
|
21
27
|
end
|
22
28
|
|
29
|
+
# Serialize a job object using MessagePack.
|
30
|
+
# @parameter job [Object] The job object to serialize.
|
31
|
+
# @returns [String] The serialized job data.
|
23
32
|
def dump(job)
|
24
33
|
@factory.pack(job)
|
25
34
|
end
|
26
35
|
|
36
|
+
# Deserialize job data using MessagePack.
|
37
|
+
# @parameter data [String] The serialized job data.
|
38
|
+
# @returns [Object] The deserialized job object.
|
27
39
|
def load(data)
|
28
40
|
@factory.unpack(data)
|
29
41
|
end
|
30
42
|
|
43
|
+
# @attribute [Async::Job::Coder::MessagePack] The default MessagePack coder instance.
|
31
44
|
DEFAULT = self.new
|
32
45
|
end
|
33
46
|
end
|
data/lib/async/job/coder.rb
CHANGED
@@ -1,17 +1,21 @@
|
|
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
|
+
# Copyright, 2025, by Shopify Inc.
|
5
6
|
|
6
|
-
require
|
7
|
+
require "json"
|
7
8
|
|
8
9
|
module Async
|
9
10
|
module Job
|
11
|
+
# A collection of coders for job serialization and deserialization.
|
12
|
+
# Provides different encoding strategies for job data, including JSON, Marshal, and MessagePack.
|
10
13
|
module Coder
|
14
|
+
# @attribute [Class] The default coder class to use for job serialization.
|
11
15
|
DEFAULT = JSON
|
12
16
|
|
13
17
|
# Type-cast for time values. See <https://bugs.ruby-lang.org/issues/20298> for background.
|
14
|
-
# @parameter value [Time
|
18
|
+
# @parameter value [Time | Integer | String | nil]
|
15
19
|
def self.Time(value)
|
16
20
|
case value
|
17
21
|
when ::Time
|
data/lib/async/job/generic.rb
CHANGED
@@ -2,26 +2,44 @@
|
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
4
|
# Copyright, 2024, by Samuel Williams.
|
5
|
+
# Copyright, 2025, by Shopify Inc.
|
5
6
|
|
6
7
|
module Async
|
7
8
|
module Job
|
9
|
+
# Represents a generic job interface that defines the minimum required structure for jobs.
|
10
|
+
# This class serves as a base for implementing specific job types and provides
|
11
|
+
# common functionality for job identification and scheduling.
|
8
12
|
class Generic
|
13
|
+
# Create and enqueue a new job with the given parameters.
|
14
|
+
# @parameter ... [Object] Parameters to pass to the job constructor.
|
15
|
+
# @returns [Async::Job::Generic] The created and enqueued job.
|
9
16
|
def self.enqueue(...)
|
10
17
|
self.new(...).enqueue
|
11
18
|
end
|
12
19
|
|
20
|
+
# Initialize a new generic job.
|
21
|
+
# @parameter id [Object] The unique identifier for this job.
|
22
|
+
# @option scheduled_at [Time | nil] The time when this job should be executed.
|
13
23
|
def initialize(id, scheduled_at: nil)
|
14
24
|
@id = id
|
15
25
|
@scheduled_at = scheduled_at
|
16
26
|
end
|
17
27
|
|
28
|
+
# @attribute [Object] The unique identifier for this job.
|
18
29
|
attr :id
|
30
|
+
# @attribute [Time | nil] The scheduled execution time for this job.
|
19
31
|
attr :scheduled_at
|
20
32
|
|
33
|
+
# Serialize the job for storage or transmission.
|
34
|
+
# This method must be implemented by subclasses.
|
35
|
+
# @raises [NotImplementedError] Always raised, must be implemented by subclasses.
|
21
36
|
def serialize
|
22
37
|
raise NotImplementedError
|
23
38
|
end
|
24
39
|
|
40
|
+
# Execute the job.
|
41
|
+
# This method must be implemented by subclasses.
|
42
|
+
# @raises [NotImplementedError] Always raised, must be implemented by subclasses.
|
25
43
|
def call
|
26
44
|
raise NotImplementedError
|
27
45
|
end
|
@@ -1,16 +1,23 @@
|
|
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
|
+
# Copyright, 2025, by Shopify Inc.
|
5
6
|
|
6
|
-
require_relative
|
7
|
+
require_relative "generic"
|
7
8
|
|
8
|
-
require
|
9
|
+
require "console/event/failure"
|
9
10
|
|
10
11
|
module Async
|
11
12
|
module Job
|
12
13
|
module Processor
|
14
|
+
# Represents an aggregate processor that batches jobs for efficient processing.
|
15
|
+
# This processor collects jobs in a buffer and processes them in batches,
|
16
|
+
# reducing the overhead of individual job processing and improving throughput.
|
13
17
|
class Aggregate < Generic
|
18
|
+
# Initialize a new aggregate processor.
|
19
|
+
# @parameter delegate [Object] The delegate object that will handle job execution.
|
20
|
+
# @option parent [Async::Task] The parent task for managing the background processing (defaults to Async::Task.current).
|
14
21
|
def initialize(delegate, parent: nil)
|
15
22
|
super(delegate)
|
16
23
|
|
@@ -21,14 +28,18 @@ module Async
|
|
21
28
|
@processing = Array.new
|
22
29
|
end
|
23
30
|
|
31
|
+
# Process a batch of jobs by delegating each job to the configured delegate.
|
32
|
+
# @parameter jobs [Array] The array of jobs to process.
|
24
33
|
def flush(jobs)
|
25
34
|
while job = jobs.shift
|
26
35
|
@delegate.call(job)
|
27
36
|
end
|
28
37
|
rescue => error
|
29
|
-
Console
|
38
|
+
Console.error(self, "Could not flush #{jobs.size} jobs.", exception: error)
|
30
39
|
end
|
31
40
|
|
41
|
+
# Run the background processing loop that continuously processes job batches.
|
42
|
+
# @parameter task [Async::Task] The task that manages the background processing.
|
32
43
|
def run(task)
|
33
44
|
while true
|
34
45
|
while @pending.empty?
|
@@ -45,8 +56,8 @@ module Async
|
|
45
56
|
end
|
46
57
|
|
47
58
|
# Start the background processing task if it is not already running.
|
48
|
-
#
|
49
|
-
# @
|
59
|
+
# @option parent [Async::Task] The parent task for the background processing (defaults to Async::Task.current).
|
60
|
+
# @returns [Boolean] True if the task was started, false if it was already running.
|
50
61
|
protected def start!(parent: Async::Task.current)
|
51
62
|
return false if @task
|
52
63
|
|
@@ -68,20 +79,22 @@ module Async
|
|
68
79
|
end
|
69
80
|
|
70
81
|
# Enqueue a job into the pending buffer.
|
71
|
-
#
|
72
82
|
# Start the background processing task if it is not already running.
|
83
|
+
# @parameter job [Object] The job to be enqueued.
|
73
84
|
def call(job)
|
74
85
|
@pending << job
|
75
86
|
|
76
87
|
start! or @ready.signal
|
77
88
|
end
|
78
89
|
|
90
|
+
# Start the processor and the background processing task.
|
79
91
|
def start
|
80
92
|
super
|
81
93
|
|
82
94
|
self.start!
|
83
95
|
end
|
84
96
|
|
97
|
+
# Stop the processor and the background processing task.
|
85
98
|
def stop
|
86
99
|
@task&.stop
|
87
100
|
|
@@ -1,23 +1,30 @@
|
|
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
|
+
# Copyright, 2025, by Shopify Inc.
|
5
6
|
|
6
|
-
require_relative
|
7
|
+
require_relative "generic"
|
7
8
|
|
8
|
-
require
|
9
|
+
require "console/event/failure"
|
9
10
|
|
10
11
|
module Async
|
11
12
|
module Job
|
12
13
|
module Processor
|
13
|
-
#
|
14
|
+
# Represents a processor that adds a configurable delay before processing each job.
|
15
|
+
# This processor is useful for rate limiting or adding artificial delays to job processing.
|
14
16
|
class Delayed < Generic
|
17
|
+
# Initialize a new delayed processor.
|
18
|
+
# @parameter delegate [Object] The delegate object that will handle job execution.
|
19
|
+
# @option delay [Float] The delay in seconds to add before processing each job (defaults to 0.1).
|
15
20
|
def initialize(delegate, delay: 0.1)
|
16
21
|
super(delegate)
|
17
22
|
|
18
23
|
@delay = delay
|
19
24
|
end
|
20
25
|
|
26
|
+
# Process a job after the configured delay.
|
27
|
+
# @parameter job [Object] The job to be processed.
|
21
28
|
def call(job)
|
22
29
|
sleep(@delay)
|
23
30
|
|
@@ -2,23 +2,32 @@
|
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
4
|
# Copyright, 2024, by Samuel Williams.
|
5
|
+
# Copyright, 2025, by Shopify Inc.
|
5
6
|
|
6
7
|
module Async
|
7
8
|
module Job
|
8
9
|
module Processor
|
10
|
+
# Represents a generic processor that delegates job execution to a provided delegate.
|
11
|
+
# This processor acts as a simple wrapper around any object that responds to call, start, and stop methods.
|
9
12
|
class Generic
|
10
|
-
|
13
|
+
# Initialize a new generic processor.
|
14
|
+
# @parameter delegate [Object] The delegate object that will handle job execution.
|
15
|
+
def initialize(delegate)
|
11
16
|
@delegate = delegate
|
12
17
|
end
|
13
18
|
|
19
|
+
# Process a job by delegating to the configured delegate.
|
20
|
+
# @parameter job [Object] The job to be processed.
|
14
21
|
def call(job)
|
15
22
|
@delegate.call(job)
|
16
23
|
end
|
17
24
|
|
25
|
+
# Start the processor by delegating to the configured delegate.
|
18
26
|
def start
|
19
27
|
@delegate.start
|
20
28
|
end
|
21
29
|
|
30
|
+
# Stop the processor by delegating to the configured delegate.
|
22
31
|
def stop
|
23
32
|
@delegate.stop
|
24
33
|
end
|
@@ -1,23 +1,33 @@
|
|
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
|
+
# Copyright, 2025, by Shopify Inc.
|
5
6
|
|
6
|
-
require_relative
|
7
|
-
require_relative
|
7
|
+
require_relative "../coder"
|
8
|
+
require_relative "generic"
|
8
9
|
|
9
|
-
require
|
10
|
+
require "async/idler"
|
10
11
|
|
11
12
|
module Async
|
12
13
|
module Job
|
13
14
|
module Processor
|
15
|
+
# Represents an inline processor that executes jobs asynchronously using Async::Idler.
|
16
|
+
# This processor handles job scheduling and executes jobs in the background,
|
17
|
+
# providing a simple way to process jobs without external dependencies.
|
14
18
|
class Inline < Generic
|
19
|
+
# Initialize a new inline processor.
|
20
|
+
# @parameter delegate [Object] The delegate object that will handle job execution.
|
21
|
+
# @option parent [Async::Idler] The parent idler for managing async tasks (defaults to a new Async::Idler).
|
15
22
|
def initialize(delegate, parent: nil)
|
16
23
|
super(delegate)
|
17
24
|
|
18
25
|
@parent = parent || Async::Idler.new
|
19
26
|
end
|
20
27
|
|
28
|
+
# Process a job asynchronously with optional scheduling.
|
29
|
+
# If the job has a scheduled_at time, the processor will wait until that time before execution.
|
30
|
+
# @parameter job [Hash] The job data containing execution details.
|
21
31
|
def call(job)
|
22
32
|
scheduled_at = Coder::Time(job["scheduled_at"])
|
23
33
|
|
@@ -32,12 +42,14 @@ module Async
|
|
32
42
|
end
|
33
43
|
end
|
34
44
|
|
45
|
+
# Start the processor by delegating to the configured delegate.
|
35
46
|
def start
|
36
|
-
@delegate
|
47
|
+
@delegate.start
|
37
48
|
end
|
38
49
|
|
50
|
+
# Stop the processor by delegating to the configured delegate.
|
39
51
|
def stop
|
40
|
-
@delegate
|
52
|
+
@delegate.stop
|
41
53
|
end
|
42
54
|
end
|
43
55
|
end
|
data/lib/async/job/processor.rb
CHANGED
@@ -1,13 +1,20 @@
|
|
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
|
+
# Copyright, 2025, by Shopify Inc.
|
5
6
|
|
6
|
-
require_relative
|
7
|
+
require_relative "processor/inline"
|
7
8
|
|
8
9
|
module Async
|
9
10
|
module Job
|
11
|
+
# Represents a collection of job processors that handle the execution of jobs.
|
12
|
+
# Provides different processing strategies including inline, aggregate, delayed, and generic processors.
|
10
13
|
module Processor
|
14
|
+
# Create a new processor instance with the specified type and options.
|
15
|
+
# @option processor [Class] The processor class to instantiate (defaults to Inline).
|
16
|
+
# @option **options [Hash] Additional options to pass to the processor constructor.
|
17
|
+
# @returns [Object] A new processor instance.
|
11
18
|
def self.new(processor: Inline, **options)
|
12
19
|
processor.new(**options)
|
13
20
|
end
|
data/lib/async/job/queue.rb
CHANGED
@@ -2,28 +2,44 @@
|
|
2
2
|
|
3
3
|
# Released under the MIT License.
|
4
4
|
# Copyright, 2024, by Samuel Williams.
|
5
|
+
# Copyright, 2025, by Shopify Inc.
|
5
6
|
|
6
7
|
module Async
|
7
8
|
module Job
|
9
|
+
# Represents a job queue that manages the client and server components of a job processing system.
|
10
|
+
# The queue acts as a facade that provides a unified interface for both enqueueing jobs
|
11
|
+
# and managing the processing server lifecycle.
|
8
12
|
class Queue
|
13
|
+
# Initialize a new job queue.
|
14
|
+
# @parameter client [Object] The client component for enqueueing jobs.
|
15
|
+
# @parameter server [Object] The server component for processing jobs.
|
16
|
+
# @parameter delegate [Object] The delegate that will execute the jobs.
|
9
17
|
def initialize(client, server, delegate)
|
10
18
|
@client = client
|
11
19
|
@server = server
|
12
20
|
@delegate = delegate
|
13
21
|
end
|
14
22
|
|
23
|
+
# @attribute [Object] The client component for enqueueing jobs.
|
15
24
|
attr :client
|
25
|
+
|
26
|
+
# @attribute [Object] The server component for processing jobs.
|
16
27
|
attr :server
|
28
|
+
|
29
|
+
# @attribute [Object] The delegate that will execute the jobs.
|
17
30
|
attr :delegate
|
18
31
|
|
32
|
+
# Enqueue a job using the client component.
|
19
33
|
def call(...)
|
20
34
|
@client.call(...)
|
21
35
|
end
|
22
36
|
|
37
|
+
# Start the job processing server.
|
23
38
|
def start
|
24
39
|
@server.start
|
25
40
|
end
|
26
41
|
|
42
|
+
# Stop the job processing server.
|
27
43
|
def stop
|
28
44
|
@server.stop
|
29
45
|
end
|
data/lib/async/job/version.rb
CHANGED
data/lib/async/job.rb
CHANGED
@@ -1,9 +1,17 @@
|
|
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
|
+
# Copyright, 2025, by Shopify Inc.
|
5
6
|
|
6
|
-
require_relative
|
7
|
-
require_relative
|
8
|
-
require_relative
|
9
|
-
require_relative
|
7
|
+
require_relative "job/version"
|
8
|
+
require_relative "job/queue"
|
9
|
+
require_relative "job/builder"
|
10
|
+
require_relative "job/buffer"
|
11
|
+
|
12
|
+
# @namespace
|
13
|
+
module Async
|
14
|
+
# @namespace
|
15
|
+
module Job
|
16
|
+
end
|
17
|
+
end
|
data/license.md
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# MIT License
|
2
2
|
|
3
|
-
Copyright, 2024, by Samuel Williams.
|
3
|
+
Copyright, 2024-2025, by Samuel Williams.
|
4
4
|
Copyright, 2024, by Alexey Ivanov.
|
5
|
+
Copyright, 2025, by Shopify Inc.
|
5
6
|
|
6
7
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
8
|
of this software and associated documentation files (the "Software"), to deal
|
data/readme.md
CHANGED
@@ -14,6 +14,70 @@ Please see the [project documentation](https://socketry.github.io/async-job/) fo
|
|
14
14
|
|
15
15
|
- [Aggregate Queue](https://socketry.github.io/async-job/guides/aggregate-queue/index) - This guide explains how to use the Aggregate queue to reduce input latency and improve the performance of your application.
|
16
16
|
|
17
|
+
## Releases
|
18
|
+
|
19
|
+
Please see the [project releases](https://socketry.github.io/async-job/releases/index) for all releases.
|
20
|
+
|
21
|
+
### v0.10.1
|
22
|
+
|
23
|
+
- Add release notes and modernize code.
|
24
|
+
- Add external tests.
|
25
|
+
- Improve test formatting and modernize code.
|
26
|
+
- Achieve 100% test coverage.
|
27
|
+
- Achieve 100% documentation coverage.
|
28
|
+
- Add agent context.
|
29
|
+
|
30
|
+
### v0.10.0
|
31
|
+
|
32
|
+
- **Breaking Change**: Extract redis support into separate gem.
|
33
|
+
- Remove block argument from job processing as it's no longer particularly useful.
|
34
|
+
|
35
|
+
### v0.9.2
|
36
|
+
|
37
|
+
- Add documentation.
|
38
|
+
- Revert `fail` -\> `retry` behavior.
|
39
|
+
|
40
|
+
### v0.9.1
|
41
|
+
|
42
|
+
- Minor improvements.
|
43
|
+
|
44
|
+
### v0.9.0
|
45
|
+
|
46
|
+
- **Breaking Change**: Reorganize processor code and add delayed processor.
|
47
|
+
- **Breaking Change**: Rename `queue` -\> `processor` and `pipeline` -\> `queue`.
|
48
|
+
- **Breaking Change**: Rename pipeline producer/consumer -\> client/server.
|
49
|
+
- **Breaking Change**: Rename `Backend` -\> `Queue`.
|
50
|
+
- Add generic backend implementation.
|
51
|
+
- Fix some words and reduce logging.
|
52
|
+
|
53
|
+
### v0.8.0
|
54
|
+
|
55
|
+
- Add `#start`/`#stop` methods.
|
56
|
+
|
57
|
+
### v0.7.1
|
58
|
+
|
59
|
+
- Minor improvements to aggregate backend.
|
60
|
+
- Ensure aggregate buffer shuts down gracefully (\#4).
|
61
|
+
|
62
|
+
### v0.7.0
|
63
|
+
|
64
|
+
- Add aggregation backend.
|
65
|
+
- Add documentation regarding aggregate backend.
|
66
|
+
- Prefer `before do` ... in tests.
|
67
|
+
|
68
|
+
### v0.6.0
|
69
|
+
|
70
|
+
- Add support for delegate pass-through.
|
71
|
+
- Modernize gem.
|
72
|
+
- Add client and server example (\#3).
|
73
|
+
- Fix gem name in guide.
|
74
|
+
|
75
|
+
### v0.5.0
|
76
|
+
|
77
|
+
- Add benchmark example.
|
78
|
+
- Add support for `Async::Idler`.
|
79
|
+
- Add link to `async-job-adapter-active_job`.
|
80
|
+
|
17
81
|
## See Also
|
18
82
|
|
19
83
|
- [async-job-processor-redis](https://github.com/socketry/async-job-processor-redis) - Redis processor for `async-job` (similar to Sidekiq).
|
data/releases.md
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
# Releases
|
2
|
+
|
3
|
+
## v0.10.1
|
4
|
+
|
5
|
+
- Add release notes and modernize code.
|
6
|
+
- Add external tests.
|
7
|
+
- Improve test formatting and modernize code.
|
8
|
+
- Achieve 100% test coverage.
|
9
|
+
- Achieve 100% documentation coverage.
|
10
|
+
- Add agent context.
|
11
|
+
|
12
|
+
## v0.10.0
|
13
|
+
|
14
|
+
- **Breaking Change**: Extract redis support into separate gem.
|
15
|
+
- Remove block argument from job processing as it's no longer particularly useful.
|
16
|
+
|
17
|
+
## v0.9.2
|
18
|
+
|
19
|
+
- Add documentation.
|
20
|
+
- Revert `fail` -\> `retry` behavior.
|
21
|
+
|
22
|
+
## v0.9.1
|
23
|
+
|
24
|
+
- Minor improvements.
|
25
|
+
|
26
|
+
## v0.9.0
|
27
|
+
|
28
|
+
- **Breaking Change**: Reorganize processor code and add delayed processor.
|
29
|
+
- **Breaking Change**: Rename `queue` -\> `processor` and `pipeline` -\> `queue`.
|
30
|
+
- **Breaking Change**: Rename pipeline producer/consumer -\> client/server.
|
31
|
+
- **Breaking Change**: Rename `Backend` -\> `Queue`.
|
32
|
+
- Add generic backend implementation.
|
33
|
+
- Fix some words and reduce logging.
|
34
|
+
|
35
|
+
## v0.8.0
|
36
|
+
|
37
|
+
- Add `#start`/`#stop` methods.
|
38
|
+
|
39
|
+
## v0.7.1
|
40
|
+
|
41
|
+
- Minor improvements to aggregate backend.
|
42
|
+
- Ensure aggregate buffer shuts down gracefully (\#4).
|
43
|
+
|
44
|
+
## v0.7.0
|
45
|
+
|
46
|
+
- Add aggregation backend.
|
47
|
+
- Add documentation regarding aggregate backend.
|
48
|
+
- Prefer `before do` ... in tests.
|
49
|
+
|
50
|
+
## v0.6.0
|
51
|
+
|
52
|
+
- Add support for delegate pass-through.
|
53
|
+
- Modernize gem.
|
54
|
+
- Add client and server example (\#3).
|
55
|
+
- Fix gem name in guide.
|
56
|
+
|
57
|
+
## v0.5.0
|
58
|
+
|
59
|
+
- Add benchmark example.
|
60
|
+
- Add support for `Async::Idler`.
|
61
|
+
- Add link to `async-job-adapter-active_job`.
|
62
|
+
|
63
|
+
## v0.4.2
|
64
|
+
|
65
|
+
- "Fix" JSON coder.
|
66
|
+
|
67
|
+
## v0.4.1
|
68
|
+
|
69
|
+
- Fix enqueue typo.
|
70
|
+
- Support returning nil =\> no-op in `Builder#build`.
|
71
|
+
|
72
|
+
## v0.4.0
|
73
|
+
|
74
|
+
- Add more documentation.
|
75
|
+
- Modernize gem.
|
76
|
+
- Add pipeline builder.
|
77
|
+
- **Breaking Change**: Use String key for "scheduled\_at".
|
78
|
+
- **Breaking Change**: Prefer `delegate` terminology for next step in the queue.
|
79
|
+
- **Breaking Change**: Rename `enqueue` -\> `call` for consistency with queue metaphor.
|
80
|
+
- **Breaking Change**: Rename `perform_at` -\> `scheduled_at`.
|
81
|
+
- Add support for coders, and remove `schedule` in favour of `enqueue`.
|
82
|
+
- Add redis to workflows.
|
83
|
+
|
84
|
+
## v0.3.0
|
85
|
+
|
86
|
+
- Add inline backend + explicit handler for processing jobs.
|
87
|
+
|
88
|
+
## v0.2.1
|
89
|
+
|
90
|
+
- Minor fixes.
|
91
|
+
|
92
|
+
## v0.2.0
|
93
|
+
|
94
|
+
- Add generic backend constructor + tests.
|
95
|
+
|
96
|
+
## v0.1.0
|
97
|
+
|
98
|
+
- Don't log all the things.
|
99
|
+
- Move ActiveJob adapter code to `async-job-adapter-active_job`.
|
100
|
+
- Add ActiveJobServer service.
|
101
|
+
- Fix invalid syntax.
|
102
|
+
- Add utopia-project for documentation.
|
103
|
+
- Add some basic tests.
|
104
|
+
- Add active\_job adapter.
|
105
|
+
|
106
|
+
## v0.0.0
|
107
|
+
|
108
|
+
- Initial release with `bake-gem` for release management.
|
109
|
+
- Add example client and server.
|
110
|
+
- Split `test.rb` -\> `client.rb` and `server.rb` for easier testing.
|
111
|
+
- Tidy up job store implementation.
|
112
|
+
- Add generic job implementation.
|
113
|
+
- Redis backend working.
|
114
|
+
- Initial noodling.
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,12 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: async-job
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.10.
|
4
|
+
version: 0.10.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
8
|
+
- Shopify Inc.
|
8
9
|
- Alexey Ivanov
|
9
|
-
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain:
|
12
12
|
- |
|
@@ -38,7 +38,7 @@ cert_chain:
|
|
38
38
|
Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
|
39
39
|
voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
|
40
40
|
-----END CERTIFICATE-----
|
41
|
-
date:
|
41
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
42
42
|
dependencies:
|
43
43
|
- !ruby/object:Gem::Dependency
|
44
44
|
name: async
|
@@ -54,8 +54,6 @@ dependencies:
|
|
54
54
|
- - "~>"
|
55
55
|
- !ruby/object:Gem::Version
|
56
56
|
version: '2.9'
|
57
|
-
description:
|
58
|
-
email:
|
59
57
|
executables: []
|
60
58
|
extensions: []
|
61
59
|
extra_rdoc_files: []
|
@@ -76,13 +74,12 @@ files:
|
|
76
74
|
- lib/async/job/version.rb
|
77
75
|
- license.md
|
78
76
|
- readme.md
|
79
|
-
|
77
|
+
- releases.md
|
80
78
|
licenses:
|
81
79
|
- MIT
|
82
80
|
metadata:
|
83
81
|
documentation_uri: https://socketry.github.io/async-job/
|
84
82
|
source_code_uri: https://github.com/socketry/async-job
|
85
|
-
post_install_message:
|
86
83
|
rdoc_options: []
|
87
84
|
require_paths:
|
88
85
|
- lib
|
@@ -90,15 +87,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
90
87
|
requirements:
|
91
88
|
- - ">="
|
92
89
|
- !ruby/object:Gem::Version
|
93
|
-
version: '3.
|
90
|
+
version: '3.2'
|
94
91
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
92
|
requirements:
|
96
93
|
- - ">="
|
97
94
|
- !ruby/object:Gem::Version
|
98
95
|
version: '0'
|
99
96
|
requirements: []
|
100
|
-
rubygems_version: 3.
|
101
|
-
signing_key:
|
97
|
+
rubygems_version: 3.6.7
|
102
98
|
specification_version: 4
|
103
99
|
summary: An asynchronous job queue for Ruby.
|
104
100
|
test_files: []
|
metadata.gz.sig
CHANGED
Binary file
|