cloudtasker 0.12.rc9 → 0.12.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/.github/workflows/test.yml +1 -5
- data/CHANGELOG.md +39 -3
- data/README.md +56 -6
- data/app/controllers/cloudtasker/worker_controller.rb +4 -1
- data/docs/BATCH_JOBS.md +34 -2
- data/gemfiles/google_cloud_tasks_1.0.gemfile.lock +114 -105
- data/gemfiles/google_cloud_tasks_1.1.gemfile.lock +114 -105
- data/gemfiles/google_cloud_tasks_1.2.gemfile.lock +114 -105
- data/gemfiles/google_cloud_tasks_1.3.gemfile.lock +114 -105
- data/gemfiles/rails_5.2.gemfile.lock +59 -50
- data/gemfiles/rails_6.0.gemfile.lock +59 -50
- data/lib/cloudtasker/backend/redis_task.rb +1 -1
- data/lib/cloudtasker/batch/extension/worker.rb +1 -1
- data/lib/cloudtasker/batch/job.rb +12 -10
- data/lib/cloudtasker/config.rb +26 -2
- data/lib/cloudtasker/local_server.rb +1 -1
- data/lib/cloudtasker/unique_job/job.rb +5 -12
- data/lib/cloudtasker/version.rb +1 -1
- data/lib/cloudtasker/worker_handler.rb +2 -0
- data/lib/cloudtasker.rb +1 -0
- metadata +7 -8
- data/app/controllers/cloudtasker/application_controller.rb +0 -8
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: ..
|
3
3
|
specs:
|
4
|
-
cloudtasker (0.12.
|
4
|
+
cloudtasker (0.12.1)
|
5
5
|
activesupport
|
6
6
|
connection_pool
|
7
7
|
fugit
|
@@ -68,35 +68,35 @@ GEM
|
|
68
68
|
minitest (~> 5.1)
|
69
69
|
tzinfo (~> 1.1)
|
70
70
|
zeitwerk (~> 2.1, >= 2.1.8)
|
71
|
-
addressable (2.
|
71
|
+
addressable (2.8.0)
|
72
72
|
public_suffix (>= 2.0.2, < 5.0)
|
73
|
-
appraisal (2.4.
|
73
|
+
appraisal (2.4.1)
|
74
74
|
bundler
|
75
75
|
rake
|
76
76
|
thor (>= 0.14.0)
|
77
77
|
ast (2.4.2)
|
78
|
-
async (1.
|
78
|
+
async (1.30.1)
|
79
79
|
console (~> 1.10)
|
80
80
|
nio4r (~> 2.3)
|
81
81
|
timers (~> 4.1)
|
82
|
-
async-http (0.
|
83
|
-
async (
|
84
|
-
async-io (
|
85
|
-
async-pool (
|
86
|
-
protocol-http (~> 0.
|
87
|
-
protocol-http1 (~> 0.
|
82
|
+
async-http (0.56.5)
|
83
|
+
async (>= 1.25)
|
84
|
+
async-io (>= 1.28)
|
85
|
+
async-pool (>= 0.2)
|
86
|
+
protocol-http (~> 0.22.0)
|
87
|
+
protocol-http1 (~> 0.14.0)
|
88
88
|
protocol-http2 (~> 0.14.0)
|
89
|
-
async-http-faraday (0.
|
89
|
+
async-http-faraday (0.11.0)
|
90
90
|
async-http (~> 0.42)
|
91
91
|
faraday
|
92
|
-
async-io (1.
|
93
|
-
async
|
94
|
-
async-pool (0.3.
|
95
|
-
async (
|
92
|
+
async-io (1.32.2)
|
93
|
+
async
|
94
|
+
async-pool (0.3.8)
|
95
|
+
async (>= 1.25)
|
96
96
|
builder (3.2.4)
|
97
|
-
concurrent-ruby (1.1.
|
97
|
+
concurrent-ruby (1.1.9)
|
98
98
|
connection_pool (2.2.5)
|
99
|
-
console (1.
|
99
|
+
console (1.13.1)
|
100
100
|
fiber-local
|
101
101
|
crack (0.4.5)
|
102
102
|
rexml
|
@@ -105,22 +105,32 @@ GEM
|
|
105
105
|
erubi (1.10.0)
|
106
106
|
et-orbi (1.2.4)
|
107
107
|
tzinfo
|
108
|
-
faraday (1.
|
108
|
+
faraday (1.7.0)
|
109
|
+
faraday-em_http (~> 1.0)
|
110
|
+
faraday-em_synchrony (~> 1.0)
|
109
111
|
faraday-excon (~> 1.1)
|
112
|
+
faraday-httpclient (~> 1.0.1)
|
110
113
|
faraday-net_http (~> 1.0)
|
111
114
|
faraday-net_http_persistent (~> 1.1)
|
115
|
+
faraday-patron (~> 1.0)
|
116
|
+
faraday-rack (~> 1.0)
|
112
117
|
multipart-post (>= 1.2, < 3)
|
113
118
|
ruby2_keywords (>= 0.0.4)
|
119
|
+
faraday-em_http (1.0.0)
|
120
|
+
faraday-em_synchrony (1.0.0)
|
114
121
|
faraday-excon (1.1.0)
|
115
122
|
faraday-http-cache (2.2.0)
|
116
123
|
faraday (>= 0.8)
|
124
|
+
faraday-httpclient (1.0.1)
|
117
125
|
faraday-net_http (1.0.1)
|
118
|
-
faraday-net_http_persistent (1.
|
126
|
+
faraday-net_http_persistent (1.2.0)
|
127
|
+
faraday-patron (1.0.0)
|
128
|
+
faraday-rack (1.0.0)
|
119
129
|
fiber-local (1.0.0)
|
120
|
-
fugit (1.
|
130
|
+
fugit (1.5.1)
|
121
131
|
et-orbi (~> 1.1, >= 1.1.8)
|
122
132
|
raabro (~> 1.4)
|
123
|
-
github_changelog_generator (1.16.
|
133
|
+
github_changelog_generator (1.16.4)
|
124
134
|
activesupport
|
125
135
|
async (>= 1.25.0)
|
126
136
|
async-http-faraday
|
@@ -129,9 +139,8 @@ GEM
|
|
129
139
|
octokit (~> 4.6)
|
130
140
|
rainbow (>= 2.2.1)
|
131
141
|
rake (>= 10.0)
|
132
|
-
|
133
|
-
|
134
|
-
activesupport (>= 4.2.0)
|
142
|
+
globalid (0.5.2)
|
143
|
+
activesupport (>= 5.0)
|
135
144
|
google-cloud-tasks (1.5.1)
|
136
145
|
google-gax (~> 1.8)
|
137
146
|
googleapis-common-protos (>= 1.3.9, < 2.0)
|
@@ -143,21 +152,21 @@ GEM
|
|
143
152
|
googleauth (~> 0.9)
|
144
153
|
grpc (~> 1.24)
|
145
154
|
rly (~> 0.2.3)
|
146
|
-
google-protobuf (3.
|
155
|
+
google-protobuf (3.17.3)
|
147
156
|
googleapis-common-protos (1.3.11)
|
148
157
|
google-protobuf (~> 3.14)
|
149
158
|
googleapis-common-protos-types (>= 1.0.6, < 2.0)
|
150
159
|
grpc (~> 1.27)
|
151
|
-
googleapis-common-protos-types (1.0
|
160
|
+
googleapis-common-protos-types (1.1.0)
|
152
161
|
google-protobuf (~> 3.14)
|
153
|
-
googleauth (0.
|
162
|
+
googleauth (0.17.0)
|
154
163
|
faraday (>= 0.17.3, < 2.0)
|
155
164
|
jwt (>= 1.4, < 3.0)
|
156
165
|
memoist (~> 0.16)
|
157
166
|
multi_json (~> 1.11)
|
158
167
|
os (>= 0.9, < 2.0)
|
159
168
|
signet (~> 0.14)
|
160
|
-
grpc (1.
|
169
|
+
grpc (1.38.0)
|
161
170
|
google-protobuf (~> 3.15)
|
162
171
|
googleapis-common-protos-types (~> 1.0)
|
163
172
|
grpc-google-iam-v1 (0.6.11)
|
@@ -168,8 +177,8 @@ GEM
|
|
168
177
|
i18n (1.8.10)
|
169
178
|
concurrent-ruby (~> 1.0)
|
170
179
|
jaro_winkler (1.5.4)
|
171
|
-
jwt (2.2.
|
172
|
-
loofah (2.
|
180
|
+
jwt (2.2.3)
|
181
|
+
loofah (2.12.0)
|
173
182
|
crass (~> 1.0.2)
|
174
183
|
nokogiri (>= 1.5.9)
|
175
184
|
mail (2.7.1)
|
@@ -181,26 +190,26 @@ GEM
|
|
181
190
|
mimemagic (0.3.10)
|
182
191
|
nokogiri (~> 1)
|
183
192
|
rake
|
184
|
-
mini_mime (1.1.
|
185
|
-
mini_portile2 (2.
|
193
|
+
mini_mime (1.1.1)
|
194
|
+
mini_portile2 (2.6.1)
|
186
195
|
minitest (5.14.4)
|
187
196
|
multi_json (1.15.0)
|
188
197
|
multipart-post (2.1.1)
|
189
|
-
nio4r (2.5.
|
190
|
-
nokogiri (1.
|
191
|
-
mini_portile2 (~> 2.
|
198
|
+
nio4r (2.5.8)
|
199
|
+
nokogiri (1.12.3)
|
200
|
+
mini_portile2 (~> 2.6.1)
|
192
201
|
racc (~> 1.4)
|
193
|
-
octokit (4.
|
202
|
+
octokit (4.21.0)
|
194
203
|
faraday (>= 0.9)
|
195
204
|
sawyer (~> 0.8.0, >= 0.5.3)
|
196
205
|
os (1.1.1)
|
197
206
|
parallel (1.20.1)
|
198
|
-
parser (3.0.
|
207
|
+
parser (3.0.2.0)
|
199
208
|
ast (~> 2.4.1)
|
200
209
|
protocol-hpack (1.4.2)
|
201
|
-
protocol-http (0.
|
202
|
-
protocol-http1 (0.
|
203
|
-
protocol-http (~> 0.
|
210
|
+
protocol-http (0.22.5)
|
211
|
+
protocol-http1 (0.14.2)
|
212
|
+
protocol-http (~> 0.22)
|
204
213
|
protocol-http2 (0.14.2)
|
205
214
|
protocol-hpack (~> 1.4)
|
206
215
|
protocol-http (~> 0.18)
|
@@ -228,7 +237,7 @@ GEM
|
|
228
237
|
rails-dom-testing (2.0.3)
|
229
238
|
activesupport (>= 4.2.0)
|
230
239
|
nokogiri (>= 1.6)
|
231
|
-
rails-html-sanitizer (1.
|
240
|
+
rails-html-sanitizer (1.4.2)
|
232
241
|
loofah (~> 2.3)
|
233
242
|
railties (6.0.0)
|
234
243
|
actionpack (= 6.0.0)
|
@@ -237,8 +246,8 @@ GEM
|
|
237
246
|
rake (>= 0.8.7)
|
238
247
|
thor (>= 0.20.3, < 2.0)
|
239
248
|
rainbow (3.0.0)
|
240
|
-
rake (13.0.
|
241
|
-
redis (4.
|
249
|
+
rake (13.0.6)
|
250
|
+
redis (4.4.0)
|
242
251
|
retriable (3.1.2)
|
243
252
|
rexml (3.2.5)
|
244
253
|
rly (0.2.3)
|
@@ -255,7 +264,7 @@ GEM
|
|
255
264
|
rspec-mocks (3.10.2)
|
256
265
|
diff-lcs (>= 1.2.0, < 2.0)
|
257
266
|
rspec-support (~> 3.10.0)
|
258
|
-
rspec-rails (5.0.
|
267
|
+
rspec-rails (5.0.2)
|
259
268
|
actionpack (>= 5.2)
|
260
269
|
activesupport (>= 5.2)
|
261
270
|
railties (>= 5.2)
|
@@ -274,11 +283,11 @@ GEM
|
|
274
283
|
rubocop-rspec (1.37.0)
|
275
284
|
rubocop (>= 0.68.1)
|
276
285
|
ruby-progressbar (1.11.0)
|
277
|
-
ruby2_keywords (0.0.
|
286
|
+
ruby2_keywords (0.0.5)
|
278
287
|
sawyer (0.8.2)
|
279
288
|
addressable (>= 2.3.5)
|
280
289
|
faraday (> 0.8, < 2.0)
|
281
|
-
semantic_logger (4.
|
290
|
+
semantic_logger (4.8.2)
|
282
291
|
concurrent-ruby (~> 1.0)
|
283
292
|
signet (0.15.0)
|
284
293
|
addressable (~> 2.3)
|
@@ -300,11 +309,11 @@ GEM
|
|
300
309
|
tzinfo (1.2.9)
|
301
310
|
thread_safe (~> 0.1)
|
302
311
|
unicode-display_width (1.6.1)
|
303
|
-
webmock (3.
|
304
|
-
addressable (>= 2.
|
312
|
+
webmock (3.14.0)
|
313
|
+
addressable (>= 2.8.0)
|
305
314
|
crack (>= 0.3.2)
|
306
315
|
hashdiff (>= 0.4.0, < 2.0.0)
|
307
|
-
websocket-driver (0.7.
|
316
|
+
websocket-driver (0.7.5)
|
308
317
|
websocket-extensions (>= 0.1.0)
|
309
318
|
websocket-extensions (0.1.5)
|
310
319
|
zeitwerk (2.4.2)
|
@@ -330,4 +339,4 @@ DEPENDENCIES
|
|
330
339
|
webmock
|
331
340
|
|
332
341
|
BUNDLED WITH
|
333
|
-
2.2.
|
342
|
+
2.2.26
|
@@ -39,7 +39,7 @@ module Cloudtasker
|
|
39
39
|
def self.all
|
40
40
|
if redis.exists?(key)
|
41
41
|
# Use Schedule Set if available
|
42
|
-
redis.smembers(key).map { |id| find(id) }
|
42
|
+
redis.smembers(key).map { |id| find(id) }.compact
|
43
43
|
else
|
44
44
|
# Fallback to redis key matching and migrate tasks
|
45
45
|
# to use Task Set instead.
|
@@ -73,8 +73,12 @@ module Cloudtasker
|
|
73
73
|
# Load extension if not loaded already on the worker class
|
74
74
|
worker.class.include(Extension::Worker) unless worker.class <= Extension::Worker
|
75
75
|
|
76
|
-
# Add batch
|
76
|
+
# Add batch and parent batch to worker
|
77
77
|
worker.batch = new(worker)
|
78
|
+
worker.parent_batch = worker.batch.parent_batch
|
79
|
+
|
80
|
+
# Return the batch
|
81
|
+
worker.batch
|
78
82
|
end
|
79
83
|
|
80
84
|
#
|
@@ -259,9 +263,7 @@ module Cloudtasker
|
|
259
263
|
migrate_batch_state_to_redis_hash
|
260
264
|
|
261
265
|
# Update the batch state batch_id entry with the new status
|
262
|
-
redis.
|
263
|
-
redis.hset(batch_state_gid, batch_id, status) if redis.hexists(batch_state_gid, batch_id)
|
264
|
-
end
|
266
|
+
redis.hset(batch_state_gid, batch_id, status) if redis.hexists(batch_state_gid, batch_id)
|
265
267
|
end
|
266
268
|
|
267
269
|
#
|
@@ -273,10 +275,7 @@ module Cloudtasker
|
|
273
275
|
migrate_batch_state_to_redis_hash
|
274
276
|
|
275
277
|
# Check that all child jobs have completed
|
276
|
-
redis.
|
277
|
-
# Check that all children are complete
|
278
|
-
redis.hvals(batch_state_gid).all? { |e| COMPLETION_STATUSES.include?(e) }
|
279
|
-
end
|
278
|
+
redis.hvals(batch_state_gid).all? { |e| COMPLETION_STATUSES.include?(e) }
|
280
279
|
end
|
281
280
|
|
282
281
|
#
|
@@ -427,8 +426,11 @@ module Cloudtasker
|
|
427
426
|
# Perform job
|
428
427
|
yield
|
429
428
|
|
430
|
-
# Save batch
|
431
|
-
setup
|
429
|
+
# Save batch if child jobs added
|
430
|
+
setup if jobs.any?
|
431
|
+
|
432
|
+
# Save parent batch if batch expanded
|
433
|
+
parent_batch&.setup if parent_batch&.jobs&.any?
|
432
434
|
|
433
435
|
# Complete batch
|
434
436
|
complete(:completed)
|
data/lib/cloudtasker/config.rb
CHANGED
@@ -7,7 +7,8 @@ module Cloudtasker
|
|
7
7
|
class Config
|
8
8
|
attr_accessor :redis, :store_payloads_in_redis
|
9
9
|
attr_writer :secret, :gcp_location_id, :gcp_project_id,
|
10
|
-
:gcp_queue_prefix, :processor_path, :logger, :mode, :max_retries,
|
10
|
+
:gcp_queue_prefix, :processor_path, :logger, :mode, :max_retries,
|
11
|
+
:dispatch_deadline, :on_error, :on_dead
|
11
12
|
|
12
13
|
# Max Cloud Task size in bytes
|
13
14
|
MAX_TASK_SIZE = 100 * 1024 # 100 KB
|
@@ -51,6 +52,9 @@ module Cloudtasker
|
|
51
52
|
MIN_DISPATCH_DEADLINE = 15 # seconds
|
52
53
|
MAX_DISPATCH_DEADLINE = 30 * 60 # 30 minutes
|
53
54
|
|
55
|
+
# Default on_error Proc
|
56
|
+
DEFAULT_ON_ERROR = ->(error, worker) {}
|
57
|
+
|
54
58
|
# The number of times jobs will be attempted before declaring them dead.
|
55
59
|
#
|
56
60
|
# With the default retry configuration (maxDoublings = 16 and minBackoff = 0.100s)
|
@@ -229,11 +233,31 @@ module Cloudtasker
|
|
229
233
|
# @return [String] The cloudtasker secret
|
230
234
|
#
|
231
235
|
def secret
|
232
|
-
@secret
|
236
|
+
@secret ||= (
|
233
237
|
defined?(Rails) && Rails.application.credentials&.dig(:secret_key_base)
|
234
238
|
) || raise(StandardError, SECRET_MISSING_ERROR)
|
235
239
|
end
|
236
240
|
|
241
|
+
#
|
242
|
+
# Return a Proc invoked whenever a worker runtime error is raised.
|
243
|
+
# See Cloudtasker::WorkerHandler.with_worker_handling
|
244
|
+
#
|
245
|
+
# @return [Proc] A Proc handler
|
246
|
+
#
|
247
|
+
def on_error
|
248
|
+
@on_error || DEFAULT_ON_ERROR
|
249
|
+
end
|
250
|
+
|
251
|
+
#
|
252
|
+
# Return a Proc invoked whenever a worker DeadWorkerError is raised.
|
253
|
+
# See Cloudtasker::WorkerHandler.with_worker_handling
|
254
|
+
#
|
255
|
+
# @return [Proc] A Proc handler
|
256
|
+
#
|
257
|
+
def on_dead
|
258
|
+
@on_dead || DEFAULT_ON_ERROR
|
259
|
+
end
|
260
|
+
|
237
261
|
#
|
238
262
|
# Return the chain of client middlewares.
|
239
263
|
#
|
@@ -149,25 +149,18 @@ module Cloudtasker
|
|
149
149
|
# if taken by another job.
|
150
150
|
#
|
151
151
|
def lock!
|
152
|
-
redis.
|
153
|
-
|
152
|
+
lock_acquired = redis.set(unique_gid, id, nx: true, ex: lock_ttl)
|
153
|
+
lock_already_acquired = !lock_acquired && redis.get(unique_gid) == id
|
154
154
|
|
155
|
-
|
156
|
-
raise(LockError, locked_id) if locked_id && locked_id != id
|
157
|
-
|
158
|
-
# Take job lock if the lock is currently free
|
159
|
-
redis.set(unique_gid, id, ex: lock_ttl) unless locked_id
|
160
|
-
end
|
155
|
+
raise(LockError) unless lock_acquired || lock_already_acquired
|
161
156
|
end
|
162
157
|
|
163
158
|
#
|
164
159
|
# Delete the job lock.
|
165
160
|
#
|
166
161
|
def unlock!
|
167
|
-
redis.
|
168
|
-
|
169
|
-
redis.del(unique_gid) if locked_id == id
|
170
|
-
end
|
162
|
+
locked_id = redis.get(unique_gid)
|
163
|
+
redis.del(unique_gid) if locked_id == id
|
171
164
|
end
|
172
165
|
end
|
173
166
|
end
|
data/lib/cloudtasker/version.rb
CHANGED
@@ -102,9 +102,11 @@ module Cloudtasker
|
|
102
102
|
# Delete stored args payload if job is dead
|
103
103
|
redis.del(args_payload_key) if args_payload_key
|
104
104
|
log_execution_error(worker, e)
|
105
|
+
Cloudtasker.config.on_dead.call(e, worker)
|
105
106
|
raise(e)
|
106
107
|
rescue StandardError => e
|
107
108
|
log_execution_error(worker, e)
|
109
|
+
Cloudtasker.config.on_error.call(e, worker)
|
108
110
|
raise(e)
|
109
111
|
end
|
110
112
|
|
data/lib/cloudtasker.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloudtasker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.12.
|
4
|
+
version: 0.12.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Arnaud Lachaume
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-08-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -324,7 +324,6 @@ files:
|
|
324
324
|
- README.md
|
325
325
|
- Rakefile
|
326
326
|
- _config.yml
|
327
|
-
- app/controllers/cloudtasker/application_controller.rb
|
328
327
|
- app/controllers/cloudtasker/worker_controller.rb
|
329
328
|
- bin/console
|
330
329
|
- bin/setup
|
@@ -416,7 +415,7 @@ metadata:
|
|
416
415
|
homepage_uri: https://github.com/keypup-io/cloudtasker
|
417
416
|
source_code_uri: https://github.com/keypup-io/cloudtasker
|
418
417
|
changelog_uri: https://github.com/keypup-io/cloudtasker/master/tree/CHANGELOG.md
|
419
|
-
post_install_message:
|
418
|
+
post_install_message:
|
420
419
|
rdoc_options: []
|
421
420
|
require_paths:
|
422
421
|
- lib
|
@@ -427,12 +426,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
427
426
|
version: '0'
|
428
427
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
429
428
|
requirements:
|
430
|
-
- - "
|
429
|
+
- - ">="
|
431
430
|
- !ruby/object:Gem::Version
|
432
|
-
version:
|
431
|
+
version: '0'
|
433
432
|
requirements: []
|
434
433
|
rubygems_version: 3.0.0
|
435
|
-
signing_key:
|
434
|
+
signing_key:
|
436
435
|
specification_version: 4
|
437
436
|
summary: Background jobs for Ruby using Google Cloud Tasks (beta)
|
438
437
|
test_files: []
|