cloudtasker 0.10.rc5 → 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
- data/.github/workflows/test.yml +7 -3
- data/.rubocop.yml +7 -1
- data/Appraisals +16 -0
- data/CHANGELOG.md +32 -4
- data/README.md +169 -37
- data/app/controllers/cloudtasker/worker_controller.rb +11 -2
- data/cloudtasker.gemspec +3 -3
- data/docs/UNIQUE_JOBS.md +62 -0
- data/gemfiles/semantic_logger_3.4.gemfile +7 -0
- data/gemfiles/semantic_logger_4.6.gemfile +7 -0
- data/gemfiles/semantic_logger_4.7.0.gemfile +7 -0
- data/gemfiles/semantic_logger_4.7.2.gemfile +7 -0
- data/gemfiles/semantic_logger_4.7.gemfile +7 -0
- data/lib/cloudtasker/backend/google_cloud_task.rb +19 -7
- data/lib/cloudtasker/backend/memory_task.rb +17 -5
- data/lib/cloudtasker/backend/redis_task.rb +2 -1
- data/lib/cloudtasker/batch/middleware/server.rb +1 -1
- data/lib/cloudtasker/config.rb +3 -0
- data/lib/cloudtasker/cron/job.rb +0 -5
- data/lib/cloudtasker/cron/middleware/server.rb +1 -1
- data/lib/cloudtasker/cron/schedule.rb +0 -3
- data/lib/cloudtasker/unique_job.rb +27 -0
- data/lib/cloudtasker/unique_job/job.rb +41 -6
- data/lib/cloudtasker/unique_job/middleware/client.rb +1 -1
- data/lib/cloudtasker/unique_job/middleware/server.rb +1 -1
- data/lib/cloudtasker/version.rb +1 -1
- data/lib/cloudtasker/worker.rb +43 -9
- data/lib/cloudtasker/worker_handler.rb +3 -26
- data/lib/cloudtasker/worker_logger.rb +2 -2
- metadata +39 -6
data/lib/cloudtasker/version.rb
CHANGED
data/lib/cloudtasker/worker.rb
CHANGED
@@ -8,7 +8,7 @@ module Cloudtasker
|
|
8
8
|
base.extend(ClassMethods)
|
9
9
|
base.attr_writer :job_queue
|
10
10
|
base.attr_accessor :job_args, :job_id, :job_meta, :job_reenqueued, :job_retries,
|
11
|
-
:perform_started_at, :perform_ended_at
|
11
|
+
:perform_started_at, :perform_ended_at, :task_id
|
12
12
|
end
|
13
13
|
|
14
14
|
#
|
@@ -47,7 +47,7 @@ module Cloudtasker
|
|
47
47
|
return nil unless worker_klass.include?(self)
|
48
48
|
|
49
49
|
# Return instantiated worker
|
50
|
-
worker_klass.new(payload.slice(:job_queue, :job_args, :job_id, :job_meta, :job_retries))
|
50
|
+
worker_klass.new(payload.slice(:job_queue, :job_args, :job_id, :job_meta, :job_retries, :task_id))
|
51
51
|
rescue NameError
|
52
52
|
nil
|
53
53
|
end
|
@@ -140,12 +140,13 @@ module Cloudtasker
|
|
140
140
|
# @param [Array<any>] job_args The list of perform args.
|
141
141
|
# @param [String] job_id A unique ID identifying this job.
|
142
142
|
#
|
143
|
-
def initialize(job_queue: nil, job_args: nil, job_id: nil, job_meta: {}, job_retries: 0)
|
143
|
+
def initialize(job_queue: nil, job_args: nil, job_id: nil, job_meta: {}, job_retries: 0, task_id: nil)
|
144
144
|
@job_args = job_args || []
|
145
145
|
@job_id = job_id || SecureRandom.uuid
|
146
146
|
@job_meta = MetaStore.new(job_meta)
|
147
147
|
@job_retries = job_retries || 0
|
148
148
|
@job_queue = job_queue
|
149
|
+
@task_id = task_id
|
149
150
|
end
|
150
151
|
|
151
152
|
#
|
@@ -197,18 +198,36 @@ module Cloudtasker
|
|
197
198
|
raise(e)
|
198
199
|
end
|
199
200
|
|
201
|
+
#
|
202
|
+
# Return a unix timestamp specifying when to run the task.
|
203
|
+
#
|
204
|
+
# @param [Integer, nil] interval The time to wait.
|
205
|
+
# @param [Integer, nil] time_at The time at which the job should run.
|
206
|
+
#
|
207
|
+
# @return [Integer, nil] The Unix timestamp.
|
208
|
+
#
|
209
|
+
def schedule_time(interval: nil, time_at: nil)
|
210
|
+
return nil unless interval || time_at
|
211
|
+
|
212
|
+
# Generate the complete Unix timestamp
|
213
|
+
(time_at || Time.now).to_i + interval.to_i
|
214
|
+
end
|
215
|
+
|
200
216
|
#
|
201
217
|
# Enqueue a worker, with or without delay.
|
202
218
|
#
|
203
219
|
# @param [Integer] interval The delay in seconds.
|
204
|
-
#
|
205
220
|
# @param [Time, Integer] interval The time at which the job should run
|
206
221
|
#
|
207
222
|
# @return [Cloudtasker::CloudTask] The Google Task response
|
208
223
|
#
|
209
|
-
def schedule(
|
210
|
-
|
211
|
-
|
224
|
+
def schedule(**args)
|
225
|
+
# Evaluate when to schedule the job
|
226
|
+
time_at = schedule_time(args)
|
227
|
+
|
228
|
+
# Schedule job through client middlewares
|
229
|
+
Cloudtasker.config.client_middleware.invoke(self, time_at: time_at) do
|
230
|
+
WorkerHandler.new(self).schedule(time_at: time_at)
|
212
231
|
end
|
213
232
|
end
|
214
233
|
|
@@ -250,7 +269,8 @@ module Cloudtasker
|
|
250
269
|
job_args: job_args,
|
251
270
|
job_meta: job_meta.to_h,
|
252
271
|
job_retries: job_retries,
|
253
|
-
job_queue: job_queue
|
272
|
+
job_queue: job_queue,
|
273
|
+
task_id: task_id
|
254
274
|
}
|
255
275
|
end
|
256
276
|
|
@@ -276,6 +296,20 @@ module Cloudtasker
|
|
276
296
|
other.is_a?(self.class) && other.job_id == job_id
|
277
297
|
end
|
278
298
|
|
299
|
+
#
|
300
|
+
# Return the max number of retries allowed for this job.
|
301
|
+
#
|
302
|
+
# The order of precedence for retry lookup is:
|
303
|
+
# - Worker `max_retries` method
|
304
|
+
# - Class `max_retries` option
|
305
|
+
# - Cloudtasker `max_retries` config option
|
306
|
+
#
|
307
|
+
# @return [Integer] The number of retries
|
308
|
+
#
|
309
|
+
def job_max_retries
|
310
|
+
@job_max_retries ||= (try(:max_retries, *job_args) || self.class.max_retries)
|
311
|
+
end
|
312
|
+
|
279
313
|
#
|
280
314
|
# Return true if the job has excceeded its maximum number
|
281
315
|
# of retries
|
@@ -283,7 +317,7 @@ module Cloudtasker
|
|
283
317
|
# @return [Boolean] True if the job is dead
|
284
318
|
#
|
285
319
|
def job_dead?
|
286
|
-
job_retries >=
|
320
|
+
job_retries >= job_max_retries
|
287
321
|
end
|
288
322
|
|
289
323
|
#
|
@@ -56,11 +56,6 @@ module Cloudtasker
|
|
56
56
|
with_worker_handling(input_payload, &:execute)
|
57
57
|
end
|
58
58
|
|
59
|
-
# TODO: do not delete redis payload if job has been re-enqueued
|
60
|
-
# worker.job_reenqueued
|
61
|
-
#
|
62
|
-
# Idea: change with_worker_handling to with_worker_handling and build the worker
|
63
|
-
# inside the with_worker_handling block.
|
64
59
|
#
|
65
60
|
# Local middleware used to retrieve the job arg payload from cache
|
66
61
|
# if a arg payload reference is present.
|
@@ -210,35 +205,17 @@ module Cloudtasker
|
|
210
205
|
}.merge(worker_args_payload)
|
211
206
|
end
|
212
207
|
|
213
|
-
#
|
214
|
-
# Return a protobuf timestamp specifying how to wait
|
215
|
-
# before running a task.
|
216
|
-
#
|
217
|
-
# @param [Integer, nil] interval The time to wait.
|
218
|
-
# @param [Integer, nil] time_at The time at which the job should run.
|
219
|
-
#
|
220
|
-
# @return [Integer, nil] The Unix timestamp.
|
221
|
-
#
|
222
|
-
def schedule_time(interval: nil, time_at: nil)
|
223
|
-
return nil unless interval || time_at
|
224
|
-
|
225
|
-
# Generate the complete Unix timestamp
|
226
|
-
(time_at || Time.now).to_i + interval.to_i
|
227
|
-
end
|
228
|
-
|
229
208
|
#
|
230
209
|
# Schedule the task on GCP Cloud Task.
|
231
210
|
#
|
232
|
-
# @param [Integer, nil]
|
211
|
+
# @param [Integer, nil] time_at A unix timestamp specifying when to run the job.
|
233
212
|
# Leave to `nil` to run now.
|
234
213
|
#
|
235
214
|
# @return [Cloudtasker::CloudTask] The Google Task response
|
236
215
|
#
|
237
|
-
def schedule(
|
216
|
+
def schedule(time_at: nil)
|
238
217
|
# Generate task payload
|
239
|
-
task = task_payload.merge(
|
240
|
-
schedule_time: schedule_time(interval: interval, time_at: time_at)
|
241
|
-
).compact
|
218
|
+
task = task_payload.merge(schedule_time: time_at).compact
|
242
219
|
|
243
220
|
# Create and return remote task
|
244
221
|
CloudTask.create(task)
|
@@ -11,7 +11,7 @@ module Cloudtasker
|
|
11
11
|
end
|
12
12
|
|
13
13
|
# Only log the job meta information by default (exclude arguments)
|
14
|
-
DEFAULT_CONTEXT_PROCESSOR = ->(worker) { worker.to_h.slice(:worker, :job_id, :job_meta, :job_queue) }
|
14
|
+
DEFAULT_CONTEXT_PROCESSOR = ->(worker) { worker.to_h.slice(:worker, :job_id, :job_meta, :job_queue, :task_id) }
|
15
15
|
|
16
16
|
#
|
17
17
|
# Build a new instance of the class.
|
@@ -142,7 +142,7 @@ module Cloudtasker
|
|
142
142
|
#
|
143
143
|
def log_message(level, msg, &block)
|
144
144
|
# Merge log-specific context into worker-specific context
|
145
|
-
payload_block = -> { log_block.call.merge(block&.call || {}) }
|
145
|
+
payload_block = ->(*_args) { log_block.call.merge(block&.call || {}) }
|
146
146
|
|
147
147
|
# ActiveSupport::Logger does not support passing a payload through a block on top
|
148
148
|
# of a message.
|
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.10.
|
4
|
+
version: 0.10.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Arnaud Lachaume
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-05
|
11
|
+
date: 2020-10-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -54,6 +54,20 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: google-cloud-tasks
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: jwt
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
73
|
- - ">="
|
@@ -67,7 +81,7 @@ dependencies:
|
|
67
81
|
- !ruby/object:Gem::Version
|
68
82
|
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
84
|
+
name: redis
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
87
|
- - ">="
|
@@ -81,7 +95,7 @@ dependencies:
|
|
81
95
|
- !ruby/object:Gem::Version
|
82
96
|
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
98
|
+
name: retriable
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
86
100
|
requirements:
|
87
101
|
- - ">="
|
@@ -192,6 +206,20 @@ dependencies:
|
|
192
206
|
- - '='
|
193
207
|
- !ruby/object:Gem::Version
|
194
208
|
version: 1.37.0
|
209
|
+
- !ruby/object:Gem::Dependency
|
210
|
+
name: semantic_logger
|
211
|
+
requirement: !ruby/object:Gem::Requirement
|
212
|
+
requirements:
|
213
|
+
- - ">="
|
214
|
+
- !ruby/object:Gem::Version
|
215
|
+
version: '0'
|
216
|
+
type: :development
|
217
|
+
prerelease: false
|
218
|
+
version_requirements: !ruby/object:Gem::Requirement
|
219
|
+
requirements:
|
220
|
+
- - ">="
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: '0'
|
195
223
|
- !ruby/object:Gem::Dependency
|
196
224
|
name: timecop
|
197
225
|
requirement: !ruby/object:Gem::Requirement
|
@@ -310,6 +338,11 @@ files:
|
|
310
338
|
- gemfiles/rails_5.2.gemfile.lock
|
311
339
|
- gemfiles/rails_6.0.gemfile
|
312
340
|
- gemfiles/rails_6.0.gemfile.lock
|
341
|
+
- gemfiles/semantic_logger_3.4.gemfile
|
342
|
+
- gemfiles/semantic_logger_4.6.gemfile
|
343
|
+
- gemfiles/semantic_logger_4.7.0.gemfile
|
344
|
+
- gemfiles/semantic_logger_4.7.2.gemfile
|
345
|
+
- gemfiles/semantic_logger_4.7.gemfile
|
313
346
|
- lib/cloudtasker.rb
|
314
347
|
- lib/cloudtasker/authentication_error.rb
|
315
348
|
- lib/cloudtasker/authenticator.rb
|
@@ -378,9 +411,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
378
411
|
version: '0'
|
379
412
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
380
413
|
requirements:
|
381
|
-
- - "
|
414
|
+
- - ">="
|
382
415
|
- !ruby/object:Gem::Version
|
383
|
-
version:
|
416
|
+
version: '0'
|
384
417
|
requirements: []
|
385
418
|
rubygems_version: 3.0.0
|
386
419
|
signing_key:
|