postburner 0.9.0.rc.1 → 1.0.0.pre.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/README.md +1082 -507
- data/app/models/postburner/job.rb +163 -39
- data/app/models/postburner/tracked_job.rb +83 -0
- data/bin/postburner +91 -0
- data/bin/rails +14 -0
- data/config/environment.rb +3 -0
- data/config/postburner.yml +22 -0
- data/config/postburner.yml.example +142 -0
- data/lib/postburner/active_job/adapter.rb +163 -0
- data/lib/postburner/active_job/execution.rb +109 -0
- data/lib/postburner/active_job/payload.rb +157 -0
- data/lib/postburner/beanstalkd.rb +97 -0
- data/lib/postburner/configuration.rb +202 -0
- data/lib/postburner/connection.rb +113 -0
- data/lib/postburner/engine.rb +1 -1
- data/lib/postburner/queue_config.rb +151 -0
- data/lib/postburner/strategies/queue.rb +20 -6
- data/lib/postburner/tracked.rb +171 -0
- data/lib/postburner/version.rb +1 -1
- data/lib/postburner/workers/base.rb +210 -0
- data/lib/postburner/workers/worker.rb +480 -0
- data/lib/postburner.rb +78 -7
- metadata +43 -11
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveJob
|
|
4
|
+
module QueueAdapters
|
|
5
|
+
# Postburner adapter for ActiveJob.
|
|
6
|
+
#
|
|
7
|
+
# Provides dual-mode job execution:
|
|
8
|
+
# - **Default mode**: Fast execution via Beanstalkd only
|
|
9
|
+
# - **Tracked mode** (opt-in): Full PostgreSQL audit trail
|
|
10
|
+
#
|
|
11
|
+
# ## Usage
|
|
12
|
+
#
|
|
13
|
+
# @example Configure in Rails
|
|
14
|
+
# # config/application.rb
|
|
15
|
+
# config.active_job.queue_adapter = :postburner
|
|
16
|
+
#
|
|
17
|
+
# @example Default job (fast)
|
|
18
|
+
# class SendEmail < ApplicationJob
|
|
19
|
+
# def perform(user_id)
|
|
20
|
+
# # No PostgreSQL overhead, executes quickly
|
|
21
|
+
# end
|
|
22
|
+
# end
|
|
23
|
+
#
|
|
24
|
+
# @example Tracked job (opt-in for audit trail)
|
|
25
|
+
# class ProcessPayment < ApplicationJob
|
|
26
|
+
# include Postburner::Tracked
|
|
27
|
+
# tracked # ← Enables PostgreSQL tracking
|
|
28
|
+
#
|
|
29
|
+
# def perform(payment_id)
|
|
30
|
+
# log "Processing payment..."
|
|
31
|
+
# # Full audit trail: logs, timing, errors
|
|
32
|
+
# end
|
|
33
|
+
# end
|
|
34
|
+
#
|
|
35
|
+
class PostburnerAdapter
|
|
36
|
+
# Enqueues a job for immediate execution.
|
|
37
|
+
#
|
|
38
|
+
# @param job [ActiveJob::Base] The job to enqueue
|
|
39
|
+
#
|
|
40
|
+
# @return [void]
|
|
41
|
+
#
|
|
42
|
+
def enqueue(job)
|
|
43
|
+
enqueue_at(job, nil)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Enqueues a job for execution at a specific time.
|
|
47
|
+
#
|
|
48
|
+
# @param job [ActiveJob::Base] The job to enqueue
|
|
49
|
+
# @param timestamp [Time, nil] When to execute the job (nil = immediate)
|
|
50
|
+
#
|
|
51
|
+
# @return [void]
|
|
52
|
+
#
|
|
53
|
+
def enqueue_at(job, timestamp)
|
|
54
|
+
if tracked?(job)
|
|
55
|
+
enqueue_tracked(job, timestamp)
|
|
56
|
+
else
|
|
57
|
+
enqueue_default(job, timestamp)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
# Checks if a job should be tracked in PostgreSQL.
|
|
64
|
+
#
|
|
65
|
+
# Detects tracking by checking if the job class includes the
|
|
66
|
+
# Postburner::Tracked module.
|
|
67
|
+
#
|
|
68
|
+
# @param job [ActiveJob::Base] The job instance
|
|
69
|
+
#
|
|
70
|
+
# @return [Boolean] true if tracked, false otherwise
|
|
71
|
+
#
|
|
72
|
+
def tracked?(job)
|
|
73
|
+
job.class.included_modules.include?(Postburner::Tracked)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Enqueues a tracked job (with PostgreSQL audit trail).
|
|
77
|
+
#
|
|
78
|
+
# Creates a Postburner::TrackedJob record, then queues minimal payload
|
|
79
|
+
# to Beanstalkd with just the job ID reference.
|
|
80
|
+
#
|
|
81
|
+
# @param job [ActiveJob::Base] The job instance
|
|
82
|
+
# @param timestamp [Time, nil] When to execute the job
|
|
83
|
+
#
|
|
84
|
+
# @return [void]
|
|
85
|
+
#
|
|
86
|
+
def enqueue_tracked(job, timestamp)
|
|
87
|
+
# Create Postburner::TrackedJob record
|
|
88
|
+
tracked_job = Postburner::TrackedJob.create!(
|
|
89
|
+
args: Postburner::ActiveJob::Payload.serialize_for_tracked(job),
|
|
90
|
+
run_at: timestamp,
|
|
91
|
+
queued_at: Time.zone.now
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
# Calculate delay for Beanstalkd
|
|
95
|
+
delay = timestamp ? [(timestamp.to_f - Time.now.to_f).to_i, 0].max : 0
|
|
96
|
+
|
|
97
|
+
# Queue to Beanstalkd with minimal payload
|
|
98
|
+
Postburner.connected do |conn|
|
|
99
|
+
tube_name = expand_tube_name(job.queue_name)
|
|
100
|
+
|
|
101
|
+
# Get priority and TTR from class configuration or fall back to defaults
|
|
102
|
+
pri = job.class.respond_to?(:queue_priority) && job.class.queue_priority ||
|
|
103
|
+
Postburner.configuration.default_priority
|
|
104
|
+
ttr = job.class.respond_to?(:queue_ttr) && job.class.queue_ttr ||
|
|
105
|
+
Postburner.configuration.default_ttr
|
|
106
|
+
|
|
107
|
+
bkid = conn.tubes[tube_name].put(
|
|
108
|
+
Postburner::ActiveJob::Payload.tracked_payload(job, tracked_job.id),
|
|
109
|
+
pri: pri,
|
|
110
|
+
delay: delay,
|
|
111
|
+
ttr: ttr
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
# Update tracked_job with Beanstalkd ID
|
|
115
|
+
tracked_job.update_column(:bkid, bkid)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Enqueues a default job (Beanstalkd only, no PostgreSQL).
|
|
120
|
+
#
|
|
121
|
+
# Queues full job data to Beanstalkd for fast execution without
|
|
122
|
+
# PostgreSQL overhead.
|
|
123
|
+
#
|
|
124
|
+
# @param job [ActiveJob::Base] The job instance
|
|
125
|
+
# @param timestamp [Time, nil] When to execute the job
|
|
126
|
+
#
|
|
127
|
+
# @return [void]
|
|
128
|
+
#
|
|
129
|
+
def enqueue_default(job, timestamp)
|
|
130
|
+
delay = timestamp ? [(timestamp.to_f - Time.now.to_f).to_i, 0].max : 0
|
|
131
|
+
|
|
132
|
+
Postburner.connected do |conn|
|
|
133
|
+
tube_name = expand_tube_name(job.queue_name)
|
|
134
|
+
|
|
135
|
+
# Get priority and TTR from class configuration or fall back to defaults
|
|
136
|
+
pri = job.class.respond_to?(:queue_priority) && job.class.queue_priority ||
|
|
137
|
+
Postburner.configuration.default_priority
|
|
138
|
+
ttr = job.class.respond_to?(:queue_ttr) && job.class.queue_ttr ||
|
|
139
|
+
Postburner.configuration.default_ttr
|
|
140
|
+
|
|
141
|
+
conn.tubes[tube_name].put(
|
|
142
|
+
Postburner::ActiveJob::Payload.default_payload(job),
|
|
143
|
+
pri: pri,
|
|
144
|
+
delay: delay,
|
|
145
|
+
ttr: ttr
|
|
146
|
+
)
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Expands queue name to full tube name with environment prefix.
|
|
151
|
+
#
|
|
152
|
+
# Delegates to Postburner::Configuration for consistent tube naming.
|
|
153
|
+
#
|
|
154
|
+
# @param queue_name [String] Queue name from ActiveJob
|
|
155
|
+
#
|
|
156
|
+
# @return [String] Full tube name (e.g., 'postburner.production.critical')
|
|
157
|
+
#
|
|
158
|
+
def expand_tube_name(queue_name)
|
|
159
|
+
Postburner.configuration.expand_tube_name(queue_name)
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Postburner
|
|
4
|
+
module ActiveJob
|
|
5
|
+
# Handles execution of ActiveJob jobs from Beanstalkd payloads.
|
|
6
|
+
#
|
|
7
|
+
# Supports both default jobs (fast, no PostgreSQL) and tracked jobs
|
|
8
|
+
# (full audit trail). Also handles legacy Postburner::Job format
|
|
9
|
+
# for backward compatibility.
|
|
10
|
+
#
|
|
11
|
+
class Execution
|
|
12
|
+
class << self
|
|
13
|
+
# Executes a job from a Beanstalkd payload.
|
|
14
|
+
#
|
|
15
|
+
# Automatically detects payload type (default, tracked, or legacy)
|
|
16
|
+
# and routes to the appropriate execution path.
|
|
17
|
+
#
|
|
18
|
+
# @param payload_json [String] JSON payload from Beanstalkd
|
|
19
|
+
#
|
|
20
|
+
# @return [void]
|
|
21
|
+
#
|
|
22
|
+
# @raise [StandardError] if job execution fails
|
|
23
|
+
#
|
|
24
|
+
def execute(payload_json)
|
|
25
|
+
payload = Payload.parse(payload_json)
|
|
26
|
+
|
|
27
|
+
if Payload.legacy_format?(payload)
|
|
28
|
+
execute_legacy(payload)
|
|
29
|
+
elsif Payload.tracked?(payload)
|
|
30
|
+
execute_tracked(payload)
|
|
31
|
+
else
|
|
32
|
+
execute_default(payload)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
# Executes a tracked job (with PostgreSQL audit trail).
|
|
39
|
+
#
|
|
40
|
+
# Loads the Postburner::Job record and delegates to its perform! method,
|
|
41
|
+
# which handles all the audit trail logging, timing, and error tracking.
|
|
42
|
+
#
|
|
43
|
+
# @param payload [Hash] Parsed payload
|
|
44
|
+
#
|
|
45
|
+
# @return [void]
|
|
46
|
+
#
|
|
47
|
+
def execute_tracked(payload)
|
|
48
|
+
job_id = payload['postburner_job_id']
|
|
49
|
+
|
|
50
|
+
unless job_id
|
|
51
|
+
raise ArgumentError, "Tracked job missing postburner_job_id"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Delegate to Postburner::Job.perform which handles the full lifecycle
|
|
55
|
+
Postburner::Job.perform(job_id)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Executes a default job (Beanstalkd only, no PostgreSQL).
|
|
59
|
+
#
|
|
60
|
+
# Deserializes the ActiveJob, restores its metadata, and executes it.
|
|
61
|
+
# Handles retries via ActiveJob's retry_on/discard_on mechanisms.
|
|
62
|
+
#
|
|
63
|
+
# @param payload [Hash] Parsed payload
|
|
64
|
+
#
|
|
65
|
+
# @return [void]
|
|
66
|
+
#
|
|
67
|
+
def execute_default(payload)
|
|
68
|
+
job_class = payload['job_class'].constantize
|
|
69
|
+
arguments = ::ActiveJob::Arguments.deserialize(payload['arguments'])
|
|
70
|
+
|
|
71
|
+
# Instantiate the job
|
|
72
|
+
job = job_class.new(*arguments)
|
|
73
|
+
|
|
74
|
+
# Restore job metadata
|
|
75
|
+
job.job_id = payload['job_id']
|
|
76
|
+
job.queue_name = payload['queue_name']
|
|
77
|
+
job.priority = payload['priority']
|
|
78
|
+
job.executions = payload['executions'] || 0
|
|
79
|
+
job.exception_executions = payload['exception_executions'] || {}
|
|
80
|
+
job.locale = payload['locale']
|
|
81
|
+
job.timezone = payload['timezone']
|
|
82
|
+
|
|
83
|
+
if payload['enqueued_at']
|
|
84
|
+
job.enqueued_at = Time.iso8601(payload['enqueued_at'])
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Execute the job (ActiveJob handles retry_on/discard_on)
|
|
88
|
+
job.perform_now
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Executes a legacy Postburner::Job (backward compatibility).
|
|
92
|
+
#
|
|
93
|
+
# Legacy format: { "class" => "JobClassName", "args" => [job_id] }
|
|
94
|
+
#
|
|
95
|
+
# @param payload [Hash] Parsed legacy payload
|
|
96
|
+
#
|
|
97
|
+
# @return [void]
|
|
98
|
+
#
|
|
99
|
+
def execute_legacy(payload)
|
|
100
|
+
job_class = payload['class'].constantize
|
|
101
|
+
job_id = payload['args'].first
|
|
102
|
+
|
|
103
|
+
# Delegate to the class's perform method (Postburner::Job.perform)
|
|
104
|
+
job_class.perform(job_id)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Postburner
|
|
4
|
+
module ActiveJob
|
|
5
|
+
# Handles serialization/deserialization of ActiveJob payloads for Beanstalkd.
|
|
6
|
+
#
|
|
7
|
+
# Provides consistent payload format for both default and tracked jobs, with
|
|
8
|
+
# versioning support for future format changes.
|
|
9
|
+
#
|
|
10
|
+
# ## Payload Format (V1)
|
|
11
|
+
#
|
|
12
|
+
# Both default and tracked jobs store the same ActiveJob data in Beanstalkd.
|
|
13
|
+
# The only difference is tracked jobs also persist to PostgreSQL and include
|
|
14
|
+
# a `postburner_job_id` reference.
|
|
15
|
+
#
|
|
16
|
+
# @example Default job payload
|
|
17
|
+
# {
|
|
18
|
+
# v: 1,
|
|
19
|
+
# tracked: false,
|
|
20
|
+
# postburner_job_id: nil,
|
|
21
|
+
# job_class: "SendEmail",
|
|
22
|
+
# job_id: "abc-123",
|
|
23
|
+
# queue_name: "mailers",
|
|
24
|
+
# arguments: [[1, 2, 3]],
|
|
25
|
+
# retry_count: 0,
|
|
26
|
+
# ...
|
|
27
|
+
# }
|
|
28
|
+
#
|
|
29
|
+
# @example Tracked job payload
|
|
30
|
+
# {
|
|
31
|
+
# v: 1,
|
|
32
|
+
# tracked: true,
|
|
33
|
+
# postburner_job_id: 456, # References postburner_jobs.id
|
|
34
|
+
# job_class: "ProcessPayment",
|
|
35
|
+
# job_id: "def-456",
|
|
36
|
+
# queue_name: "critical",
|
|
37
|
+
# arguments: [[789]],
|
|
38
|
+
# retry_count: 0,
|
|
39
|
+
# ...
|
|
40
|
+
# }
|
|
41
|
+
#
|
|
42
|
+
class Payload
|
|
43
|
+
VERSION = 1
|
|
44
|
+
|
|
45
|
+
class << self
|
|
46
|
+
# Generates payload structure for an ActiveJob.
|
|
47
|
+
#
|
|
48
|
+
# @param job [ActiveJob::Base] The ActiveJob instance
|
|
49
|
+
# @param tracked [Boolean] Whether this is a tracked job
|
|
50
|
+
# @param postburner_job_id [Integer, nil] Postburner::Job ID for tracked jobs
|
|
51
|
+
#
|
|
52
|
+
# @return [Hash] Payload hash
|
|
53
|
+
#
|
|
54
|
+
# @api private
|
|
55
|
+
#
|
|
56
|
+
def for_job(job, tracked: false, postburner_job_id: nil)
|
|
57
|
+
{
|
|
58
|
+
v: VERSION,
|
|
59
|
+
tracked: tracked,
|
|
60
|
+
postburner_job_id: postburner_job_id,
|
|
61
|
+
job_class: job.class.name,
|
|
62
|
+
job_id: job.job_id,
|
|
63
|
+
queue_name: job.queue_name,
|
|
64
|
+
priority: job.priority,
|
|
65
|
+
arguments: ::ActiveJob::Arguments.serialize(job.arguments),
|
|
66
|
+
executions: job.executions,
|
|
67
|
+
exception_executions: job.exception_executions || {},
|
|
68
|
+
locale: job.locale,
|
|
69
|
+
timezone: job.timezone,
|
|
70
|
+
enqueued_at: job.enqueued_at&.iso8601,
|
|
71
|
+
retry_count: 0 # For default job retry tracking
|
|
72
|
+
}
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Generates JSON payload for a default job.
|
|
76
|
+
#
|
|
77
|
+
# @param job [ActiveJob::Base] The ActiveJob instance
|
|
78
|
+
#
|
|
79
|
+
# @return [String] JSON-encoded payload
|
|
80
|
+
#
|
|
81
|
+
def default_payload(job)
|
|
82
|
+
JSON.generate(for_job(job, tracked: false))
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Generates JSON payload for a tracked job.
|
|
86
|
+
#
|
|
87
|
+
# @param job [ActiveJob::Base] The ActiveJob instance
|
|
88
|
+
# @param postburner_job_id [Integer] Postburner::Job ID
|
|
89
|
+
#
|
|
90
|
+
# @return [String] JSON-encoded payload
|
|
91
|
+
#
|
|
92
|
+
def tracked_payload(job, postburner_job_id)
|
|
93
|
+
JSON.generate(for_job(job, tracked: true, postburner_job_id: postburner_job_id))
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# Serializes ActiveJob data for PostgreSQL storage (tracked jobs).
|
|
97
|
+
#
|
|
98
|
+
# Returns the same structure as for_job but as a plain Hash
|
|
99
|
+
# (not JSON string) for storage in Postburner::Job args column.
|
|
100
|
+
#
|
|
101
|
+
# @param job [ActiveJob::Base] The ActiveJob instance
|
|
102
|
+
#
|
|
103
|
+
# @return [Hash] Payload hash for PostgreSQL storage
|
|
104
|
+
#
|
|
105
|
+
def serialize_for_tracked(job)
|
|
106
|
+
for_job(job, tracked: true).stringify_keys
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Parses and validates a JSON payload from Beanstalkd.
|
|
110
|
+
#
|
|
111
|
+
# Handles version checking and returns the parsed data.
|
|
112
|
+
#
|
|
113
|
+
# @param json_string [String] JSON payload from Beanstalkd
|
|
114
|
+
#
|
|
115
|
+
# @return [Hash] Parsed payload with string keys
|
|
116
|
+
#
|
|
117
|
+
# @raise [ArgumentError] if payload version is unknown
|
|
118
|
+
#
|
|
119
|
+
def parse(json_string)
|
|
120
|
+
data = JSON.parse(json_string)
|
|
121
|
+
|
|
122
|
+
# Handle version
|
|
123
|
+
version = data['v'] || data[:v] || 1
|
|
124
|
+
|
|
125
|
+
case version
|
|
126
|
+
when 1
|
|
127
|
+
data.is_a?(Hash) ? data.stringify_keys : data
|
|
128
|
+
else
|
|
129
|
+
raise ArgumentError, "Unknown payload version: #{version}"
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Detects if a parsed payload is for a tracked job.
|
|
134
|
+
#
|
|
135
|
+
# @param payload [Hash] Parsed payload
|
|
136
|
+
#
|
|
137
|
+
# @return [Boolean] true if tracked, false otherwise
|
|
138
|
+
#
|
|
139
|
+
def tracked?(payload)
|
|
140
|
+
payload['tracked'] == true || payload[:tracked] == true
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Detects if a parsed payload is for a legacy Postburner::Job.
|
|
144
|
+
#
|
|
145
|
+
# Legacy format: { "class" => "JobClassName", "args" => [job_id] }
|
|
146
|
+
#
|
|
147
|
+
# @param payload [Hash] Parsed payload
|
|
148
|
+
#
|
|
149
|
+
# @return [Boolean] true if legacy format
|
|
150
|
+
#
|
|
151
|
+
def legacy_format?(payload)
|
|
152
|
+
payload.key?('class') && payload.key?('args') && !payload.key?('v')
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Postburner
|
|
4
|
+
# Beanstalkd-specific configuration DSL for ActiveJob classes using Postburner.
|
|
5
|
+
#
|
|
6
|
+
# Provides consistent API with Postburner::Job for setting Beanstalkd queue
|
|
7
|
+
# priority and TTR (time-to-run). Include this module in your ActiveJob classes
|
|
8
|
+
# to use Beanstalkd-specific configuration.
|
|
9
|
+
#
|
|
10
|
+
# @note Automatically included when you include Postburner::Tracked
|
|
11
|
+
#
|
|
12
|
+
# @example Default job with Beanstalkd config
|
|
13
|
+
# class ProcessPayment < ApplicationJob
|
|
14
|
+
# include Postburner::Beanstalkd
|
|
15
|
+
#
|
|
16
|
+
# queue_as :critical
|
|
17
|
+
# queue_priority 0 # Highest priority
|
|
18
|
+
# queue_ttr 300 # 5 minutes to complete
|
|
19
|
+
#
|
|
20
|
+
# def perform(payment_id)
|
|
21
|
+
# # ...
|
|
22
|
+
# end
|
|
23
|
+
# end
|
|
24
|
+
#
|
|
25
|
+
# @example With tracking (Beanstalkd automatically included)
|
|
26
|
+
# class ProcessPayment < ApplicationJob
|
|
27
|
+
# include Postburner::Tracked # Includes Beanstalkd automatically
|
|
28
|
+
#
|
|
29
|
+
# queue_priority 0
|
|
30
|
+
# queue_ttr 600
|
|
31
|
+
#
|
|
32
|
+
# def perform(payment_id)
|
|
33
|
+
# log "Processing payment"
|
|
34
|
+
# # ...
|
|
35
|
+
# end
|
|
36
|
+
# end
|
|
37
|
+
#
|
|
38
|
+
module Beanstalkd
|
|
39
|
+
extend ActiveSupport::Concern
|
|
40
|
+
|
|
41
|
+
included do
|
|
42
|
+
class_attribute :postburner_priority, default: nil
|
|
43
|
+
class_attribute :postburner_ttr, default: nil
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
class_methods do
|
|
47
|
+
# Sets or returns the queue priority.
|
|
48
|
+
#
|
|
49
|
+
# Lower numbers = higher priority in Beanstalkd (0 is highest).
|
|
50
|
+
# Falls back to Postburner.configuration.default_priority if not set.
|
|
51
|
+
#
|
|
52
|
+
# @param pri [Integer, nil] Priority to set (0-4294967295), or nil to get current value
|
|
53
|
+
#
|
|
54
|
+
# @return [Integer, nil] Current priority when getting, nil when setting
|
|
55
|
+
#
|
|
56
|
+
# @example Set priority
|
|
57
|
+
# queue_priority 0 # Highest priority
|
|
58
|
+
#
|
|
59
|
+
# @example Get priority
|
|
60
|
+
# ProcessPayment.queue_priority # => 0
|
|
61
|
+
#
|
|
62
|
+
def queue_priority(pri = nil)
|
|
63
|
+
if pri
|
|
64
|
+
self.postburner_priority = pri
|
|
65
|
+
nil
|
|
66
|
+
else
|
|
67
|
+
postburner_priority
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Sets or returns the queue TTR (time to run).
|
|
72
|
+
#
|
|
73
|
+
# Number of seconds Beanstalkd will wait for job completion before
|
|
74
|
+
# making it available again. Falls back to Postburner.configuration.default_ttr
|
|
75
|
+
# if not set.
|
|
76
|
+
#
|
|
77
|
+
# @param ttr [Integer, nil] Timeout in seconds, or nil to get current value
|
|
78
|
+
#
|
|
79
|
+
# @return [Integer, nil] Current TTR when getting, nil when setting
|
|
80
|
+
#
|
|
81
|
+
# @example Set TTR
|
|
82
|
+
# queue_ttr 300 # 5 minutes
|
|
83
|
+
#
|
|
84
|
+
# @example Get TTR
|
|
85
|
+
# ProcessPayment.queue_ttr # => 300
|
|
86
|
+
#
|
|
87
|
+
def queue_ttr(ttr = nil)
|
|
88
|
+
if ttr
|
|
89
|
+
self.postburner_ttr = ttr
|
|
90
|
+
nil
|
|
91
|
+
else
|
|
92
|
+
postburner_ttr
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|