cloudtasker 0.12.rc9 → 0.12.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- cloudtasker (0.12.rc9)
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.7.0)
71
+ addressable (2.8.0)
72
72
  public_suffix (>= 2.0.2, < 5.0)
73
- appraisal (2.4.0)
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.29.0)
78
+ async (1.30.1)
79
79
  console (~> 1.10)
80
80
  nio4r (~> 2.3)
81
81
  timers (~> 4.1)
82
- async-http (0.54.1)
83
- async (~> 1.25)
84
- async-io (~> 1.28)
85
- async-pool (~> 0.2)
86
- protocol-http (~> 0.21.0)
87
- protocol-http1 (~> 0.13.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.9.0)
89
+ async-http-faraday (0.11.0)
90
90
  async-http (~> 0.42)
91
91
  faraday
92
- async-io (1.30.2)
93
- async (~> 1.14)
94
- async-pool (0.3.5)
95
- async (~> 1.25)
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.8)
97
+ concurrent-ruby (1.1.9)
98
98
  connection_pool (2.2.5)
99
- console (1.11.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.4.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.1.0)
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.4.4)
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.1)
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
- retriable (~> 3.0)
133
- globalid (0.4.2)
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.15.8)
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.6)
160
+ googleapis-common-protos-types (1.1.0)
152
161
  google-protobuf (~> 3.14)
153
- googleauth (0.16.1)
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.37.0)
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.2)
172
- loofah (2.9.1)
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.0)
185
- mini_portile2 (2.5.0)
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.7)
190
- nokogiri (1.11.3)
191
- mini_portile2 (~> 2.5.0)
198
+ nio4r (2.5.8)
199
+ nokogiri (1.12.3)
200
+ mini_portile2 (~> 2.6.1)
192
201
  racc (~> 1.4)
193
- octokit (4.20.0)
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.1.0)
207
+ parser (3.0.2.0)
199
208
  ast (~> 2.4.1)
200
209
  protocol-hpack (1.4.2)
201
- protocol-http (0.21.0)
202
- protocol-http1 (0.13.2)
203
- protocol-http (~> 0.19)
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.3.0)
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.3)
241
- redis (4.2.5)
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.1)
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.4)
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.7.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.12.2)
304
- addressable (>= 2.3.6)
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.3)
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.9
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.
@@ -6,7 +6,7 @@ module Cloudtasker
6
6
  # Include batch related methods onto Cloudtasker::Worker
7
7
  # See: Cloudtasker::Batch::Middleware#configure
8
8
  module Worker
9
- attr_accessor :batch
9
+ attr_accessor :batch, :parent_batch
10
10
  end
11
11
  end
12
12
  end
@@ -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 capability
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.with_lock("#{batch_state_gid}/#{batch_id}", max_wait: BATCH_MAX_LOCK_WAIT) do
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.with_lock(batch_state_gid, max_wait: BATCH_MAX_LOCK_WAIT) do
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 (if child workers have been enqueued)
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)
@@ -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, :dispatch_deadline
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
  #
@@ -84,7 +84,7 @@ module Cloudtasker
84
84
 
85
85
  # Deliver task
86
86
  begin
87
- Thread.current['task'].deliver
87
+ Thread.current['task']&.deliver
88
88
  rescue Errno::EBADF, Errno::ECONNREFUSED => e
89
89
  raise(e) unless Thread.current['attempts'] < 3
90
90
 
@@ -149,25 +149,18 @@ module Cloudtasker
149
149
  # if taken by another job.
150
150
  #
151
151
  def lock!
152
- redis.with_lock(unique_gid) do
153
- locked_id = redis.get(unique_gid)
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
- # Abort job lock process if lock is already taken by another job
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.with_lock(unique_gid) do
168
- locked_id = redis.get(unique_gid)
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Cloudtasker
4
- VERSION = '0.12.rc9'
4
+ VERSION = '0.12.1'
5
5
  end
@@ -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
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'active_support/core_ext/string/inflections'
4
+ require 'active_support/core_ext/object/try'
4
5
 
5
6
  require 'cloudtasker/version'
6
7
  require 'cloudtasker/config'
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.rc9
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-04-19 00:00:00.000000000 Z
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: 1.3.1
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: []