cloudtasker 0.1.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +4 -0
- data/.rubocop.yml +5 -0
- data/.travis.yml +10 -1
- data/Appraisals +25 -0
- data/CHANGELOG.md +25 -0
- data/Gemfile.lock +37 -4
- data/README.md +573 -6
- data/Rakefile +6 -0
- data/app/controllers/cloudtasker/application_controller.rb +2 -0
- data/app/controllers/cloudtasker/worker_controller.rb +24 -2
- data/cloudtasker.gemspec +7 -3
- data/docs/BATCH_JOBS.md +66 -0
- data/docs/CRON_JOBS.md +63 -0
- data/docs/UNIQUE_JOBS.md +127 -0
- data/exe/cloudtasker +15 -0
- data/gemfiles/.bundle/config +2 -0
- data/gemfiles/google_cloud_tasks_1.0.gemfile +9 -0
- data/gemfiles/google_cloud_tasks_1.0.gemfile.lock +263 -0
- data/gemfiles/google_cloud_tasks_1.1.gemfile +9 -0
- data/gemfiles/google_cloud_tasks_1.1.gemfile.lock +263 -0
- data/gemfiles/google_cloud_tasks_1.2.gemfile +9 -0
- data/gemfiles/google_cloud_tasks_1.2.gemfile.lock +263 -0
- data/gemfiles/google_cloud_tasks_1.3.gemfile +9 -0
- data/gemfiles/google_cloud_tasks_1.3.gemfile.lock +264 -0
- data/gemfiles/rails_4.0.gemfile +10 -0
- data/gemfiles/rails_4.1.gemfile +9 -0
- data/gemfiles/rails_4.2.gemfile +9 -0
- data/gemfiles/rails_5.0.gemfile +9 -0
- data/gemfiles/rails_5.1.gemfile +9 -0
- data/gemfiles/rails_5.2.gemfile +9 -0
- data/gemfiles/rails_5.2.gemfile.lock +247 -0
- data/gemfiles/rails_6.0.gemfile +9 -0
- data/gemfiles/rails_6.0.gemfile.lock +263 -0
- data/lib/cloudtasker.rb +21 -1
- data/lib/cloudtasker/backend/google_cloud_task.rb +139 -0
- data/lib/cloudtasker/backend/memory_task.rb +190 -0
- data/lib/cloudtasker/backend/redis_task.rb +249 -0
- data/lib/cloudtasker/batch/batch_progress.rb +19 -1
- data/lib/cloudtasker/batch/job.rb +88 -23
- data/lib/cloudtasker/batch/middleware.rb +0 -1
- data/lib/cloudtasker/cli.rb +194 -0
- data/lib/cloudtasker/cloud_task.rb +91 -0
- data/lib/cloudtasker/config.rb +64 -2
- data/lib/cloudtasker/cron/job.rb +6 -3
- data/lib/cloudtasker/cron/middleware.rb +0 -1
- data/lib/cloudtasker/cron/schedule.rb +73 -13
- data/lib/cloudtasker/dead_worker_error.rb +6 -0
- data/lib/cloudtasker/local_server.rb +74 -0
- data/lib/cloudtasker/railtie.rb +10 -0
- data/lib/cloudtasker/redis_client.rb +24 -2
- data/lib/cloudtasker/testing.rb +133 -0
- data/lib/cloudtasker/unique_job/job.rb +5 -2
- data/lib/cloudtasker/unique_job/lock/base_lock.rb +1 -1
- data/lib/cloudtasker/unique_job/lock/until_executed.rb +3 -1
- data/lib/cloudtasker/unique_job/lock/while_executing.rb +3 -1
- data/lib/cloudtasker/unique_job/middleware.rb +0 -1
- data/lib/cloudtasker/version.rb +1 -1
- data/lib/cloudtasker/worker.rb +59 -16
- data/lib/cloudtasker/{task.rb → worker_handler.rb} +10 -77
- data/lib/cloudtasker/worker_logger.rb +155 -0
- data/lib/tasks/setup_queue.rake +10 -0
- metadata +98 -9
- data/lib/cloudtasker/batch/config.rb +0 -11
- data/lib/cloudtasker/cron/config.rb +0 -11
- data/lib/cloudtasker/unique_job/config.rb +0 -10
data/lib/cloudtasker/config.rb
CHANGED
@@ -1,15 +1,24 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'logger'
|
4
|
+
|
3
5
|
module Cloudtasker
|
4
6
|
# Holds cloudtasker configuration. See Cloudtasker#configure
|
5
7
|
class Config
|
6
8
|
attr_accessor :redis
|
7
9
|
attr_writer :secret, :gcp_location_id, :gcp_project_id,
|
8
|
-
:gcp_queue_id, :
|
10
|
+
:gcp_queue_id, :processor_path, :logger, :mode, :max_retries
|
11
|
+
|
12
|
+
# Retry header in Cloud Task responses
|
13
|
+
RETRY_HEADER = 'X-CloudTasks-TaskExecutionCount'
|
9
14
|
|
15
|
+
# Default values
|
10
16
|
DEFAULT_LOCATION_ID = 'us-east1'
|
11
17
|
DEFAULT_PROCESSOR_PATH = '/cloudtasker/run'
|
12
18
|
|
19
|
+
# The number of times jobs will be attempted before declaring them dead
|
20
|
+
DEFAULT_MAX_RETRY_ATTEMPTS = 25
|
21
|
+
|
13
22
|
PROCESSOR_HOST_MISSING = <<~DOC
|
14
23
|
Missing host for processing.
|
15
24
|
Please specify a processor hostname in form of `https://some-public-dns.example.com`'
|
@@ -27,6 +36,46 @@ module Cloudtasker
|
|
27
36
|
Please specify a secret in the cloudtasker initializer or add Rails secret_key_base in your credentials
|
28
37
|
DOC
|
29
38
|
|
39
|
+
#
|
40
|
+
# The number of times jobs will be retried. This number of
|
41
|
+
# retries does not include failures due to the application being unreachable.
|
42
|
+
#
|
43
|
+
#
|
44
|
+
# @return [Integer] The number of retries
|
45
|
+
#
|
46
|
+
def max_retries
|
47
|
+
@max_retries ||= DEFAULT_MAX_RETRY_ATTEMPTS
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# The operating mode.
|
52
|
+
# - :production => process tasks via GCP Cloud Task.
|
53
|
+
# - :development => process tasks locally via Redis.
|
54
|
+
#
|
55
|
+
# @return [<Type>] <description>
|
56
|
+
#
|
57
|
+
def mode
|
58
|
+
@mode ||= environment == 'development' ? :development : :production
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# Return the current environment.
|
63
|
+
#
|
64
|
+
# @return [String] The environment name.
|
65
|
+
#
|
66
|
+
def environment
|
67
|
+
ENV['CLOUDTASKER_ENV'] || ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
|
68
|
+
end
|
69
|
+
|
70
|
+
#
|
71
|
+
# Return the Cloudtasker logger.
|
72
|
+
#
|
73
|
+
# @return [Logger, any] The cloudtasker logger.
|
74
|
+
#
|
75
|
+
def logger
|
76
|
+
@logger ||= defined?(Rails) ? Rails.logger : ::Logger.new(STDOUT)
|
77
|
+
end
|
78
|
+
|
30
79
|
#
|
31
80
|
# Return the full URL of the processor. Worker payloads will be sent
|
32
81
|
# to this URL.
|
@@ -37,6 +86,19 @@ module Cloudtasker
|
|
37
86
|
File.join(processor_host, processor_path)
|
38
87
|
end
|
39
88
|
|
89
|
+
#
|
90
|
+
# Set the processor host. In the context of Rails the host will
|
91
|
+
# also be added to the list of authorized Rails hosts.
|
92
|
+
#
|
93
|
+
# @param [String] val The processor host to set.
|
94
|
+
#
|
95
|
+
def processor_host=(val)
|
96
|
+
@processor_host = val
|
97
|
+
|
98
|
+
# Add processor host to the list of authorized hosts
|
99
|
+
Rails.application.config.hosts << val.gsub(%r{https?://}, '') if val && defined?(Rails)
|
100
|
+
end
|
101
|
+
|
40
102
|
#
|
41
103
|
# The hostname of the application processing the workers. The hostname must
|
42
104
|
# be reachable from Cloud Task.
|
@@ -93,7 +155,7 @@ module Cloudtasker
|
|
93
155
|
#
|
94
156
|
def secret
|
95
157
|
@secret || (
|
96
|
-
defined?(Rails) && Rails.application.credentials&.secret_key_base
|
158
|
+
defined?(Rails) && Rails.application.credentials&.dig(:secret_key_base)
|
97
159
|
) || raise(StandardError, SECRET_MISSING_ERROR)
|
98
160
|
end
|
99
161
|
|
data/lib/cloudtasker/cron/job.rb
CHANGED
@@ -10,6 +10,9 @@ module Cloudtasker
|
|
10
10
|
class Job
|
11
11
|
attr_reader :worker
|
12
12
|
|
13
|
+
# Key Namespace used for object saved under this class
|
14
|
+
SUB_NAMESPACE = 'job'
|
15
|
+
|
13
16
|
#
|
14
17
|
# Build a new instance of the class
|
15
18
|
#
|
@@ -29,7 +32,7 @@ module Cloudtasker
|
|
29
32
|
def key(val)
|
30
33
|
return nil if val.nil?
|
31
34
|
|
32
|
-
[
|
35
|
+
[self.class.to_s.underscore, val.to_s].join('/')
|
33
36
|
end
|
34
37
|
|
35
38
|
#
|
@@ -176,8 +179,8 @@ module Cloudtasker
|
|
176
179
|
next_worker = worker.new_instance.tap { |e| e.job_meta.set(key(:time_at), next_time.iso8601) }
|
177
180
|
|
178
181
|
# Schedule next worker
|
179
|
-
|
180
|
-
cron_schedule.update(task_id:
|
182
|
+
task = next_worker.schedule(time_at: next_time)
|
183
|
+
cron_schedule.update(task_id: task.id, job_id: next_worker.job_id)
|
181
184
|
end
|
182
185
|
|
183
186
|
#
|
@@ -8,6 +8,9 @@ module Cloudtasker
|
|
8
8
|
class Schedule
|
9
9
|
attr_accessor :id, :cron, :worker, :task_id, :job_id
|
10
10
|
|
11
|
+
# Key Namespace used for object saved under this class
|
12
|
+
SUB_NAMESPACE = 'schedule'
|
13
|
+
|
11
14
|
#
|
12
15
|
# Return the redis client.
|
13
16
|
#
|
@@ -17,6 +20,50 @@ module Cloudtasker
|
|
17
20
|
RedisClient
|
18
21
|
end
|
19
22
|
|
23
|
+
#
|
24
|
+
# Return a namespaced key.
|
25
|
+
#
|
26
|
+
# @param [String, Symbol] val The key to namespace
|
27
|
+
#
|
28
|
+
# @return [String] The namespaced key.
|
29
|
+
#
|
30
|
+
def self.key(val)
|
31
|
+
return nil if val.nil?
|
32
|
+
|
33
|
+
[to_s.underscore, val.to_s].join('/')
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# Return all schedules
|
38
|
+
#
|
39
|
+
# @return [Array<Cloudtasker::Batch::Schedule>] The list of stored schedules.
|
40
|
+
#
|
41
|
+
def self.all
|
42
|
+
redis.search(key('*')).map do |gid|
|
43
|
+
find(gid.sub(key(''), ''))
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# Synchronize list of cron schedules from a Hash. Schedules
|
49
|
+
# not listed in this hash will be removed.
|
50
|
+
#
|
51
|
+
# @example
|
52
|
+
# Cloudtasker::Cron::Schedule.load_from_hash!(
|
53
|
+
# my_job: { cron: '0 0 * * *', worker: 'MyWorker' }
|
54
|
+
# my_other_job: { cron: '0 10 * * *', worker: 'MyOtherWorker' }
|
55
|
+
# )
|
56
|
+
#
|
57
|
+
def self.load_from_hash!(hash)
|
58
|
+
schedules = hash.map do |id, config|
|
59
|
+
schedule_config = JSON.parse(config.to_json, symbolize_names: true).merge(id: id.to_s)
|
60
|
+
create(schedule_config)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Remove existing schedules which are not part of the list
|
64
|
+
all.reject { |e| schedules.include?(e) }.each { |e| delete(e.id) }
|
65
|
+
end
|
66
|
+
|
20
67
|
#
|
21
68
|
# Create a new cron schedule (or update an existing one).
|
22
69
|
#
|
@@ -25,8 +72,10 @@ module Cloudtasker
|
|
25
72
|
# @return [Cloudtasker::Cron::Schedule] The schedule instance.
|
26
73
|
#
|
27
74
|
def self.create(**opts)
|
28
|
-
|
29
|
-
|
75
|
+
redis.with_lock(key(opts[:id])) do
|
76
|
+
config = find(opts[:id]).to_h.merge(opts)
|
77
|
+
new(config).tap(&:save)
|
78
|
+
end
|
30
79
|
end
|
31
80
|
|
32
81
|
#
|
@@ -37,8 +86,7 @@ module Cloudtasker
|
|
37
86
|
# @return [Cloudtasker::Cron::Schedule] The schedule instance.
|
38
87
|
#
|
39
88
|
def self.find(id)
|
40
|
-
|
41
|
-
return nil unless (schedule_config = redis.fetch(gid))
|
89
|
+
return nil unless (schedule_config = redis.fetch(key(id)))
|
42
90
|
|
43
91
|
new(schedule_config)
|
44
92
|
end
|
@@ -49,12 +97,14 @@ module Cloudtasker
|
|
49
97
|
# @param [String] id The schedule id.
|
50
98
|
#
|
51
99
|
def self.delete(id)
|
52
|
-
|
53
|
-
|
100
|
+
redis.with_lock(key(id)) do
|
101
|
+
schedule = find(id)
|
102
|
+
return false unless schedule
|
54
103
|
|
55
|
-
|
56
|
-
|
57
|
-
|
104
|
+
# Delete task and stored schedule
|
105
|
+
CloudTask.delete(schedule.task_id) if schedule.task_id
|
106
|
+
redis.del(schedule.gid)
|
107
|
+
end
|
58
108
|
end
|
59
109
|
|
60
110
|
#
|
@@ -89,7 +139,7 @@ module Cloudtasker
|
|
89
139
|
# @return [String] The namespaced schedule id.
|
90
140
|
#
|
91
141
|
def gid
|
92
|
-
|
142
|
+
self.class.key(id)
|
93
143
|
end
|
94
144
|
|
95
145
|
#
|
@@ -206,17 +256,27 @@ module Cloudtasker
|
|
206
256
|
# then any existing cloud task is removed and a task is recreated.
|
207
257
|
#
|
208
258
|
def save(update_task: true)
|
209
|
-
return false unless valid?
|
259
|
+
return false unless valid?
|
210
260
|
|
211
261
|
# Save schedule
|
212
262
|
config_was_changed = config_changed?
|
213
263
|
redis.write(gid, to_h)
|
214
264
|
|
215
265
|
# Stop there if backend does not need update
|
216
|
-
return true unless update_task && config_was_changed
|
266
|
+
return true unless update_task && (config_was_changed || !task_id || !CloudTask.find(task_id))
|
267
|
+
|
268
|
+
# Update backend
|
269
|
+
persist_cloud_task
|
270
|
+
end
|
217
271
|
|
272
|
+
private
|
273
|
+
|
274
|
+
#
|
275
|
+
# Update the task in backend.
|
276
|
+
#
|
277
|
+
def persist_cloud_task
|
218
278
|
# Delete previous instance
|
219
|
-
|
279
|
+
CloudTask.delete(task_id) if task_id
|
220
280
|
|
221
281
|
# Schedule worker
|
222
282
|
worker_instance = Object.const_get(worker).new
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cloudtasker/backend/redis_task'
|
4
|
+
|
5
|
+
module Cloudtasker
|
6
|
+
# Process jobs stored in Redis.
|
7
|
+
# Only to be used in development.
|
8
|
+
class LocalServer
|
9
|
+
# Max number of task requests sent to the processing server
|
10
|
+
CONCURRENCY = (ENV['CLOUDTASKER_CONCURRENCY'] || 5).to_i
|
11
|
+
|
12
|
+
#
|
13
|
+
# Stop the local server.
|
14
|
+
#
|
15
|
+
def stop
|
16
|
+
@done = true
|
17
|
+
|
18
|
+
# Terminate threads and repush tasks
|
19
|
+
@threads&.each do |t|
|
20
|
+
t.terminate
|
21
|
+
t['task']&.retry_later(0, is_error: false)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Wait for main server to be done
|
25
|
+
sleep 1 while @start&.alive?
|
26
|
+
end
|
27
|
+
|
28
|
+
#
|
29
|
+
# Start the local server
|
30
|
+
#
|
31
|
+
#
|
32
|
+
def start
|
33
|
+
@start ||= Thread.new do
|
34
|
+
until @done
|
35
|
+
process_jobs
|
36
|
+
sleep 1
|
37
|
+
end
|
38
|
+
Cloudtasker.logger.info('[Cloudtasker/Server] Local server exiting...')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
# Process enqueued workers.
|
44
|
+
#
|
45
|
+
#
|
46
|
+
def process_jobs
|
47
|
+
@threads ||= []
|
48
|
+
|
49
|
+
# Remove any done thread
|
50
|
+
@threads.select!(&:alive?)
|
51
|
+
|
52
|
+
# Process tasks
|
53
|
+
while @threads.count < CONCURRENCY && (task = Cloudtasker::Backend::RedisTask.pop)
|
54
|
+
@threads << Thread.new do
|
55
|
+
Thread.current['task'] = task
|
56
|
+
Thread.current['attempts'] = 0
|
57
|
+
|
58
|
+
# Deliver task
|
59
|
+
begin
|
60
|
+
Thread.current['task'].deliver
|
61
|
+
rescue Errno::ECONNREFUSED => e
|
62
|
+
raise(e) unless Thread.current['attempts'] < 3
|
63
|
+
|
64
|
+
# Retry on connection error, in case the web server is not
|
65
|
+
# started yet.
|
66
|
+
Thread.current['attempts'] += 1
|
67
|
+
sleep(3)
|
68
|
+
retry
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -8,7 +8,7 @@ module Cloudtasker
|
|
8
8
|
module_function
|
9
9
|
|
10
10
|
# Suffix added to cache keys when locking them
|
11
|
-
|
11
|
+
LOCK_KEY_PREFIX = 'cloudtasker/lock'
|
12
12
|
|
13
13
|
#
|
14
14
|
# Return the underlying redis client.
|
@@ -61,7 +61,7 @@ module Cloudtasker
|
|
61
61
|
return nil unless cache_key
|
62
62
|
|
63
63
|
# Wait to acquire lock
|
64
|
-
lock_key = [
|
64
|
+
lock_key = [LOCK_KEY_PREFIX, cache_key].join('/')
|
65
65
|
true until client.setnx(lock_key, true)
|
66
66
|
|
67
67
|
# yield content
|
@@ -83,6 +83,28 @@ module Cloudtasker
|
|
83
83
|
del(*all_keys)
|
84
84
|
end
|
85
85
|
|
86
|
+
#
|
87
|
+
# Return all keys matching the provided patterns.
|
88
|
+
#
|
89
|
+
# @param [String] pattern A redis compatible pattern.
|
90
|
+
#
|
91
|
+
# @return [Array<String>] The list of matching keys
|
92
|
+
#
|
93
|
+
def search(pattern)
|
94
|
+
# Initialize loop variables
|
95
|
+
cursor = nil
|
96
|
+
list = []
|
97
|
+
|
98
|
+
# Scan and capture matching keys
|
99
|
+
while cursor != 0
|
100
|
+
scan = client.scan(cursor || 0, match: pattern)
|
101
|
+
list += scan[1]
|
102
|
+
cursor = scan[0].to_i
|
103
|
+
end
|
104
|
+
|
105
|
+
list
|
106
|
+
end
|
107
|
+
|
86
108
|
#
|
87
109
|
# Delegate all methods to the redis client.
|
88
110
|
#
|
@@ -0,0 +1,133 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cloudtasker/backend/memory_task'
|
4
|
+
|
5
|
+
module Cloudtasker
|
6
|
+
# Enable/Disable test mode for Cloudtasker
|
7
|
+
module Testing
|
8
|
+
module_function
|
9
|
+
|
10
|
+
#
|
11
|
+
# Set the test mode, either permanently or
|
12
|
+
# temporarily (via block).
|
13
|
+
#
|
14
|
+
# @param [Symbol] mode The test mode.
|
15
|
+
#
|
16
|
+
# @return [Symbol] The test mode.
|
17
|
+
#
|
18
|
+
def switch_test_mode(mode)
|
19
|
+
if block_given?
|
20
|
+
current_mode = @test_mode
|
21
|
+
begin
|
22
|
+
@test_mode = mode
|
23
|
+
yield
|
24
|
+
ensure
|
25
|
+
@test_mode = current_mode
|
26
|
+
end
|
27
|
+
else
|
28
|
+
@test_mode = mode
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
# Set cloudtasker to real mode temporarily
|
34
|
+
#
|
35
|
+
# @param [Proc] &block The block to run in real mode
|
36
|
+
#
|
37
|
+
def enable!(&block)
|
38
|
+
switch_test_mode(:enabled, &block)
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
# Set cloudtasker to fake mode temporarily
|
43
|
+
#
|
44
|
+
# @param [Proc] &block The block to run in fake mode
|
45
|
+
#
|
46
|
+
def fake!(&block)
|
47
|
+
switch_test_mode(:fake, &block)
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# Set cloudtasker to inline mode temporarily
|
52
|
+
#
|
53
|
+
# @param [Proc] &block The block to run in inline mode
|
54
|
+
#
|
55
|
+
def inline!(&block)
|
56
|
+
switch_test_mode(:inline, &block)
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# Return true if Cloudtasker is enabled.
|
61
|
+
#
|
62
|
+
def enabled?
|
63
|
+
!@test_mode || @test_mode == :enabled
|
64
|
+
end
|
65
|
+
|
66
|
+
#
|
67
|
+
# Return true if Cloudtasker is in fake mode.
|
68
|
+
#
|
69
|
+
# @return [Boolean] True if jobs must be processed through drain calls.
|
70
|
+
#
|
71
|
+
def fake?
|
72
|
+
@test_mode == :fake
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
# Return true if Cloudtasker is in inline mode.
|
77
|
+
#
|
78
|
+
# @return [Boolean] True if jobs are run inline.
|
79
|
+
#
|
80
|
+
def inline?
|
81
|
+
@test_mode == :inline
|
82
|
+
end
|
83
|
+
|
84
|
+
#
|
85
|
+
# Return true if tasks should be managed in memory.
|
86
|
+
#
|
87
|
+
# @return [Boolean] True if jobs are managed in memory.
|
88
|
+
#
|
89
|
+
def in_memory?
|
90
|
+
!enabled?
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# Add extra methods for testing purpose
|
95
|
+
module Worker
|
96
|
+
#
|
97
|
+
# Clear all jobs.
|
98
|
+
#
|
99
|
+
def self.clear_all
|
100
|
+
Backend::MemoryTask.clear
|
101
|
+
end
|
102
|
+
|
103
|
+
#
|
104
|
+
# Run all the jobs.
|
105
|
+
#
|
106
|
+
# @return [Array<any>] The return values of the workers perform method.
|
107
|
+
#
|
108
|
+
def self.drain_all
|
109
|
+
Backend::MemoryTask.drain
|
110
|
+
end
|
111
|
+
|
112
|
+
# Module class methods
|
113
|
+
module ClassMethods
|
114
|
+
#
|
115
|
+
# Return all jobs related to this worker class.
|
116
|
+
#
|
117
|
+
# @return [Array<Cloudtasker::Worker] The list of workers
|
118
|
+
#
|
119
|
+
def jobs
|
120
|
+
Backend::MemoryTask.jobs(to_s)
|
121
|
+
end
|
122
|
+
|
123
|
+
#
|
124
|
+
# Run all jobs related to this worker class.
|
125
|
+
#
|
126
|
+
# @return [Array<any>] The return values of the workers perform method.
|
127
|
+
#
|
128
|
+
def drain
|
129
|
+
Backend::MemoryTask.drain(to_s)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|