cloudtasker 0.11.0 → 0.12.rc5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +9 -2
- data/CHANGELOG.md +16 -1
- data/README.md +2 -2
- data/app/controllers/cloudtasker/worker_controller.rb +4 -17
- data/docs/BATCH_JOBS.md +24 -3
- data/lib/cloudtasker/backend/redis_task.rb +18 -9
- data/lib/cloudtasker/batch/job.rb +25 -9
- data/lib/cloudtasker/cron/schedule.rb +17 -8
- data/lib/cloudtasker/version.rb +1 -1
- data/lib/cloudtasker/worker.rb +45 -7
- data/lib/cloudtasker/worker_handler.rb +26 -0
- data/lib/cloudtasker/worker_logger.rb +29 -2
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a1f63a9bfefe90d0cfa0d6b567098ec72efe150894fbd878daa72fe934d27a25
|
4
|
+
data.tar.gz: 347d6358120bd83f116b569fafcd0313a96d8c34a4f6222ca20b0dedda866098
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a4ecf9ad17d612133653f70e7691fc746742c3ca62eb8f67c09bdc1992776391e755a5c674b97d0339bd74514958299062610d448b089fe5995dd6abe5756021
|
7
|
+
data.tar.gz: 231f0ba89cf89db4bdb138a1d34d10688161d156c9898da7a067783f75f930b9318a08dfdf240188e23dfa3a0e9dd59b38b1b235b5ab5038eb6727a244877017
|
data/.rubocop.yml
CHANGED
@@ -6,13 +6,15 @@ AllCops:
|
|
6
6
|
- 'vendor/**/*'
|
7
7
|
|
8
8
|
Metrics/ClassLength:
|
9
|
-
Max:
|
9
|
+
Max: 200
|
10
10
|
|
11
11
|
Metrics/ModuleLength:
|
12
12
|
Max: 150
|
13
13
|
|
14
14
|
Metrics/AbcSize:
|
15
15
|
Max: 20
|
16
|
+
Exclude:
|
17
|
+
- 'spec/support/*'
|
16
18
|
|
17
19
|
Metrics/LineLength:
|
18
20
|
Max: 120
|
@@ -47,4 +49,9 @@ Metrics/ParameterLists:
|
|
47
49
|
CountKeywordArgs: false
|
48
50
|
|
49
51
|
RSpec/MessageSpies:
|
50
|
-
Enabled: false
|
52
|
+
Enabled: false
|
53
|
+
|
54
|
+
RSpec/MultipleExpectations:
|
55
|
+
Exclude:
|
56
|
+
- 'examples/**/*'
|
57
|
+
- 'spec/integration/**/*'
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,21 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
-
## [v0.
|
3
|
+
## Latest RC [v0.12.rc5](https://github.com/keypup-io/cloudtasker/tree/v0.12.rc5) (2021-03-30)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/keypup-io/cloudtasker/compare/v0.11.0...v0.12.rc5)
|
6
|
+
|
7
|
+
**Improvements:**
|
8
|
+
- ActiveJob: do not double log errors (ActiveJob has its own error logging)
|
9
|
+
- Error logging: Use worker logger so as to include context (job args etc.)
|
10
|
+
- Error logging: Do not log exception and stack trace separately, combine them instead.
|
11
|
+
- Batch callbacks: Retry jobs when completion callback fails
|
12
|
+
- Redis: Use Redis Sets instead of key pattern matching for listing methods (Cron jobs and Local Server)
|
13
|
+
- Batch progress: restrict calculation to direct children by default. Allow depth to be specified. Calculating progress using all tree jobs created significant delays on large batches.
|
14
|
+
|
15
|
+
**Fixed bugs:**
|
16
|
+
- Retries: Enforce job retry limit on job processing. There was an edge case where jobs could be retried indefinitely on batch callback errors.
|
17
|
+
|
18
|
+
## [v0.11.0](https://github.com/keypup-io/cloudtasker/tree/v0.11.0) (2021-03-11)
|
4
19
|
|
5
20
|
[Full Changelog](https://github.com/keypup-io/cloudtasker/compare/v0.10.0...v0.11.0)
|
6
21
|
|
data/README.md
CHANGED
@@ -12,7 +12,7 @@ Cloudtasker also provides optional modules for running [cron jobs](docs/CRON_JOB
|
|
12
12
|
|
13
13
|
A local processing server is also available for development. This local server processes jobs in lieu of Cloud Tasks and allows you to work offline.
|
14
14
|
|
15
|
-
**Maturity**: This gem is production-ready. We at Keypup have already processed millions of jobs using Cloudtasker and all related extensions (cron, batch and unique jobs).
|
15
|
+
**Maturity**: This gem is production-ready. We at Keypup have already processed millions of jobs using Cloudtasker and all related extensions (cron, batch and unique jobs). We are planning to release the official `v1.0.0` somewhere in 2021, in case we've missed any edge-case bug.
|
16
16
|
|
17
17
|
## Summary
|
18
18
|
|
@@ -136,7 +136,7 @@ That's it! Your job was picked up by the Cloudtasker local server and sent for p
|
|
136
136
|
Now jump to the next section to configure your app to use Google Cloud Tasks as a backend.
|
137
137
|
|
138
138
|
## Get started with Rails & ActiveJob
|
139
|
-
**Note**: ActiveJob is supported since `0.11.0`
|
139
|
+
**Note**: ActiveJob is supported since `0.11.0`
|
140
140
|
**Note**: Cloudtasker extensions (cron, batch and unique jobs) are not available when using cloudtasker via ActiveJob.
|
141
141
|
|
142
142
|
Cloudtasker is pre-integrated with ActiveJob. Follow the steps below to get started.
|
@@ -19,32 +19,19 @@ module Cloudtasker
|
|
19
19
|
# Process payload
|
20
20
|
WorkerHandler.execute_from_payload!(payload)
|
21
21
|
head :no_content
|
22
|
-
rescue DeadWorkerError, MissingWorkerArgumentsError
|
22
|
+
rescue DeadWorkerError, MissingWorkerArgumentsError
|
23
23
|
# 205: job will NOT be retried
|
24
|
-
log_error(e)
|
25
24
|
head :reset_content
|
26
|
-
rescue InvalidWorkerError
|
25
|
+
rescue InvalidWorkerError
|
27
26
|
# 404: Job will be retried
|
28
|
-
log_error(e)
|
29
27
|
head :not_found
|
30
|
-
rescue StandardError
|
31
|
-
#
|
32
|
-
log_error(e)
|
28
|
+
rescue StandardError
|
29
|
+
# 422: Job will be retried
|
33
30
|
head :unprocessable_entity
|
34
31
|
end
|
35
32
|
|
36
33
|
private
|
37
34
|
|
38
|
-
#
|
39
|
-
# Log an error via cloudtasker logger.
|
40
|
-
#
|
41
|
-
# @param [Exception] e The error to log
|
42
|
-
#
|
43
|
-
def log_error(error)
|
44
|
-
Cloudtasker.logger.error(error)
|
45
|
-
Cloudtasker.logger.error(error.backtrace.join("\n"))
|
46
|
-
end
|
47
|
-
|
48
35
|
#
|
49
36
|
# Parse the request body and return the actual job
|
50
37
|
# payload.
|
data/docs/BATCH_JOBS.md
CHANGED
@@ -84,8 +84,29 @@ You can access progression statistics in callback using `batch.progress`. See th
|
|
84
84
|
E.g.
|
85
85
|
```ruby
|
86
86
|
def on_batch_node_complete(_child_job)
|
87
|
-
|
88
|
-
logger.info("
|
89
|
-
logger.info("
|
87
|
+
progress = batch.progress
|
88
|
+
logger.info("Total: #{progress.total}")
|
89
|
+
logger.info("Completed: #{progress.completed}")
|
90
|
+
logger.info("Progress: #{progress.percent.to_i}%")
|
91
|
+
end
|
92
|
+
```
|
93
|
+
|
94
|
+
**Since:** `v0.12.rc5`
|
95
|
+
By default the `progress` method only considers the direct child jobs to evaluate the batch progress. You can pass `depth: somenumber` to the `progress` method to calculate the actual batch progress in a more granular way. Be careful however that this method recursively calculates progress on the sub-batches and is therefore expensive.
|
96
|
+
|
97
|
+
E.g.
|
98
|
+
```ruby
|
99
|
+
def on_batch_node_complete(_child_job)
|
100
|
+
# Considers the children for batch progress calculation
|
101
|
+
progress_0 = batch.progress # same as batch.progress(depth: 0)
|
102
|
+
|
103
|
+
# Considers the children and grand-children for batch progress calculation
|
104
|
+
progress_1 = batch.progress(depth: 1)
|
105
|
+
|
106
|
+
# Considers the children, grand-children and grand-grand-children for batch progress calculation
|
107
|
+
progress_2 = batch.progress(depth: 3)
|
108
|
+
|
109
|
+
logger.info("Progress: #{progress_1.percent.to_i}%")
|
110
|
+
logger.info("Progress: #{progress_2.percent.to_i}%")
|
90
111
|
end
|
91
112
|
```
|
@@ -23,14 +23,12 @@ module Cloudtasker
|
|
23
23
|
#
|
24
24
|
# Return a namespaced key.
|
25
25
|
#
|
26
|
-
# @param [String, Symbol] val The key to namespace
|
26
|
+
# @param [String, Symbol, nil] val The key to namespace
|
27
27
|
#
|
28
28
|
# @return [String] The namespaced key.
|
29
29
|
#
|
30
|
-
def self.key(val)
|
31
|
-
|
32
|
-
|
33
|
-
[to_s.underscore, val.to_s].join('/')
|
30
|
+
def self.key(val = nil)
|
31
|
+
[to_s.underscore, val].compact.map(&:to_s).join('/')
|
34
32
|
end
|
35
33
|
|
36
34
|
#
|
@@ -39,9 +37,17 @@ module Cloudtasker
|
|
39
37
|
# @return [Array<Cloudtasker::Backend::RedisTask>] All the tasks.
|
40
38
|
#
|
41
39
|
def self.all
|
42
|
-
redis.
|
43
|
-
|
44
|
-
|
40
|
+
if redis.exists?(key)
|
41
|
+
# Use Schedule Set if available
|
42
|
+
redis.smembers(key).map { |id| find(id) }
|
43
|
+
else
|
44
|
+
# Fallback to redis key matching and migrate tasks
|
45
|
+
# to use Task Set instead.
|
46
|
+
redis.search(key('*')).map do |gid|
|
47
|
+
task_id = gid.sub(key(''), '')
|
48
|
+
redis.sadd(key, task_id)
|
49
|
+
find(task_id)
|
50
|
+
end
|
45
51
|
end
|
46
52
|
end
|
47
53
|
|
@@ -82,6 +88,7 @@ module Cloudtasker
|
|
82
88
|
|
83
89
|
# Save job
|
84
90
|
redis.write(key(id), payload)
|
91
|
+
redis.sadd(key, id)
|
85
92
|
new(payload.merge(id: id))
|
86
93
|
end
|
87
94
|
|
@@ -105,6 +112,7 @@ module Cloudtasker
|
|
105
112
|
# @param [String] id The task id.
|
106
113
|
#
|
107
114
|
def self.delete(id)
|
115
|
+
redis.srem(key, id)
|
108
116
|
redis.del(key(id))
|
109
117
|
end
|
110
118
|
|
@@ -170,13 +178,14 @@ module Cloudtasker
|
|
170
178
|
schedule_time: (Time.now + interval).to_i,
|
171
179
|
queue: queue
|
172
180
|
)
|
181
|
+
redis.sadd(self.class.key, id)
|
173
182
|
end
|
174
183
|
|
175
184
|
#
|
176
185
|
# Remove the task from the queue.
|
177
186
|
#
|
178
187
|
def destroy
|
179
|
-
|
188
|
+
self.class.delete(id)
|
180
189
|
end
|
181
190
|
|
182
191
|
#
|
@@ -13,6 +13,10 @@ module Cloudtasker
|
|
13
13
|
# List of statuses triggering a completion callback
|
14
14
|
COMPLETION_STATUSES = %w[completed dead].freeze
|
15
15
|
|
16
|
+
# These callbacks do not need to raise errors on their own
|
17
|
+
# because the jobs will be either retried or dropped
|
18
|
+
IGNORED_ERRORED_CALLBACKS = %i[on_child_error on_child_dead].freeze
|
19
|
+
|
16
20
|
#
|
17
21
|
# Return the cloudtasker redis client
|
18
22
|
#
|
@@ -250,8 +254,8 @@ module Cloudtasker
|
|
250
254
|
end
|
251
255
|
|
252
256
|
#
|
253
|
-
# Run worker callback
|
254
|
-
#
|
257
|
+
# Run worker callback. The error and dead callbacks get
|
258
|
+
# silenced should they raise an error.
|
255
259
|
#
|
256
260
|
# @param [String, Symbol] callback The callback to run.
|
257
261
|
# @param [Array<any>] *args The callback arguments.
|
@@ -261,9 +265,14 @@ module Cloudtasker
|
|
261
265
|
def run_worker_callback(callback, *args)
|
262
266
|
worker.try(callback, *args)
|
263
267
|
rescue StandardError => e
|
264
|
-
|
265
|
-
|
266
|
-
|
268
|
+
# There is no point in retrying jobs due to failure callbacks failing
|
269
|
+
# Only completion callbacks will trigger a re-run of the job because
|
270
|
+
# these do matter for batch completion
|
271
|
+
raise(e) unless IGNORED_ERRORED_CALLBACKS.include?(callback)
|
272
|
+
|
273
|
+
# Log error instead
|
274
|
+
worker.logger.error(e)
|
275
|
+
worker.logger.error("Callback #{callback} failed to run. Skipping to preserve error flow.")
|
267
276
|
end
|
268
277
|
|
269
278
|
#
|
@@ -275,7 +284,7 @@ module Cloudtasker
|
|
275
284
|
|
276
285
|
# Propagate event
|
277
286
|
parent_batch&.on_child_complete(self, status)
|
278
|
-
|
287
|
+
|
279
288
|
# The batch tree is complete. Cleanup the tree.
|
280
289
|
cleanup unless parent_batch
|
281
290
|
end
|
@@ -338,13 +347,20 @@ module Cloudtasker
|
|
338
347
|
#
|
339
348
|
# @return [Cloudtasker::Batch::BatchProgress] The batch progress.
|
340
349
|
#
|
341
|
-
def progress
|
350
|
+
def progress(depth: 0)
|
351
|
+
depth = depth.to_i
|
352
|
+
|
342
353
|
# Capture batch state
|
343
354
|
state = batch_state
|
344
355
|
|
345
|
-
#
|
356
|
+
# Return immediately if we do not need to go down the tree
|
357
|
+
return BatchProgress.new(state) if depth <= 0
|
358
|
+
|
359
|
+
# Sum batch progress of current batch and sub-batches up to the specified
|
360
|
+
# depth
|
346
361
|
state.to_h.reduce(BatchProgress.new(state)) do |memo, (child_id, child_status)|
|
347
|
-
memo + (self.class.find(child_id)&.progress
|
362
|
+
memo + (self.class.find(child_id)&.progress(depth: depth - 1) ||
|
363
|
+
BatchProgress.new(child_id => child_status))
|
348
364
|
end
|
349
365
|
end
|
350
366
|
|
@@ -21,14 +21,12 @@ module Cloudtasker
|
|
21
21
|
#
|
22
22
|
# Return a namespaced key.
|
23
23
|
#
|
24
|
-
# @param [String, Symbol] val The key to namespace
|
24
|
+
# @param [String, Symbol, nil] val The key to namespace
|
25
25
|
#
|
26
26
|
# @return [String] The namespaced key.
|
27
27
|
#
|
28
|
-
def self.key(val)
|
29
|
-
|
30
|
-
|
31
|
-
[to_s.underscore, val.to_s].join('/')
|
28
|
+
def self.key(val = nil)
|
29
|
+
[to_s.underscore, val].compact.map(&:to_s).join('/')
|
32
30
|
end
|
33
31
|
|
34
32
|
#
|
@@ -37,8 +35,17 @@ module Cloudtasker
|
|
37
35
|
# @return [Array<Cloudtasker::Batch::Schedule>] The list of stored schedules.
|
38
36
|
#
|
39
37
|
def self.all
|
40
|
-
redis.
|
41
|
-
|
38
|
+
if redis.exists?(key)
|
39
|
+
# Use Schedule Set if available
|
40
|
+
redis.smembers(key).map { |id| find(id) }
|
41
|
+
else
|
42
|
+
# Fallback to redis key matching and migrate schedules
|
43
|
+
# to use Schedule Set instead.
|
44
|
+
redis.search(key('*')).map do |gid|
|
45
|
+
schedule_id = gid.sub(key(''), '')
|
46
|
+
redis.sadd(key, schedule_id)
|
47
|
+
find(schedule_id)
|
48
|
+
end
|
42
49
|
end
|
43
50
|
end
|
44
51
|
|
@@ -90,7 +97,7 @@ module Cloudtasker
|
|
90
97
|
end
|
91
98
|
|
92
99
|
#
|
93
|
-
#
|
100
|
+
# Delete a schedule by id.
|
94
101
|
#
|
95
102
|
# @param [String] id The schedule id.
|
96
103
|
#
|
@@ -101,6 +108,7 @@ module Cloudtasker
|
|
101
108
|
|
102
109
|
# Delete task and stored schedule
|
103
110
|
CloudTask.delete(schedule.task_id) if schedule.task_id
|
111
|
+
redis.srem(key, schedule.id)
|
104
112
|
redis.del(schedule.gid)
|
105
113
|
end
|
106
114
|
end
|
@@ -270,6 +278,7 @@ module Cloudtasker
|
|
270
278
|
|
271
279
|
# Save schedule
|
272
280
|
config_was_changed = config_changed?
|
281
|
+
redis.sadd(self.class.key, id)
|
273
282
|
redis.write(gid, to_h)
|
274
283
|
|
275
284
|
# Stop there if backend does not need update
|
data/lib/cloudtasker/version.rb
CHANGED
data/lib/cloudtasker/worker.rb
CHANGED
@@ -311,13 +311,25 @@ module Cloudtasker
|
|
311
311
|
end
|
312
312
|
|
313
313
|
#
|
314
|
-
# Return true if the job
|
315
|
-
#
|
314
|
+
# Return true if the job must declared dead upon raising
|
315
|
+
# an error.
|
316
|
+
#
|
317
|
+
# @return [Boolean] True if the job must die on error.
|
318
|
+
#
|
319
|
+
def job_must_die?
|
320
|
+
job_retries >= job_max_retries
|
321
|
+
end
|
322
|
+
|
323
|
+
#
|
324
|
+
# Return true if the job has strictly excceeded its maximum number
|
325
|
+
# of retries.
|
326
|
+
#
|
327
|
+
# Used a preemptive filter when running the job.
|
316
328
|
#
|
317
329
|
# @return [Boolean] True if the job is dead
|
318
330
|
#
|
319
331
|
def job_dead?
|
320
|
-
job_retries
|
332
|
+
job_retries > job_max_retries
|
321
333
|
end
|
322
334
|
|
323
335
|
#
|
@@ -332,11 +344,35 @@ module Cloudtasker
|
|
332
344
|
(perform_ended_at - perform_started_at).ceil(3)
|
333
345
|
end
|
334
346
|
|
347
|
+
#
|
348
|
+
# Run worker callback.
|
349
|
+
#
|
350
|
+
# @param [String, Symbol] callback The callback to run.
|
351
|
+
# @param [Array<any>] *args The callback arguments.
|
352
|
+
#
|
353
|
+
# @return [any] The callback return value
|
354
|
+
#
|
355
|
+
def run_callback(callback, *args)
|
356
|
+
try(callback, *args)
|
357
|
+
end
|
358
|
+
|
335
359
|
#=============================
|
336
360
|
# Private
|
337
361
|
#=============================
|
338
362
|
private
|
339
363
|
|
364
|
+
#
|
365
|
+
# Flag the worker as dead by invoking the on_dead hook
|
366
|
+
# and raising a DeadWorkerError
|
367
|
+
#
|
368
|
+
# @param [Exception, nil] error An optional exception to be passed to the DeadWorkerError.
|
369
|
+
#
|
370
|
+
def flag_as_dead(error = nil)
|
371
|
+
run_callback(:on_dead, error || DeadWorkerError.new)
|
372
|
+
ensure
|
373
|
+
raise(DeadWorkerError, error)
|
374
|
+
end
|
375
|
+
|
340
376
|
#
|
341
377
|
# Execute the worker perform method through the middleware chain.
|
342
378
|
#
|
@@ -346,6 +382,9 @@ module Cloudtasker
|
|
346
382
|
self.perform_started_at = Time.now
|
347
383
|
|
348
384
|
Cloudtasker.config.server_middleware.invoke(self) do
|
385
|
+
# Immediately abort the job if it is already dead
|
386
|
+
flag_as_dead if job_dead?
|
387
|
+
|
349
388
|
begin
|
350
389
|
# Abort if arguments are missing. This may happen with redis arguments storage
|
351
390
|
# if Cloud Tasks times out on a job but the job still succeeds
|
@@ -356,12 +395,11 @@ module Cloudtasker
|
|
356
395
|
# Perform the job
|
357
396
|
perform(*job_args)
|
358
397
|
rescue StandardError => e
|
359
|
-
|
360
|
-
return raise(e) unless
|
398
|
+
run_callback(:on_error, e)
|
399
|
+
return raise(e) unless job_must_die?
|
361
400
|
|
362
401
|
# Flag job as dead
|
363
|
-
|
364
|
-
raise(DeadWorkerError, e)
|
402
|
+
flag_as_dead(e)
|
365
403
|
end
|
366
404
|
end
|
367
405
|
ensure
|
@@ -45,6 +45,28 @@ module Cloudtasker
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
|
+
#
|
49
|
+
# Log error on execution failure.
|
50
|
+
#
|
51
|
+
# @param [Cloudtasker::Worker, nil] worker The worker.
|
52
|
+
# @param [Exception] error The error to log.
|
53
|
+
#
|
54
|
+
# @void
|
55
|
+
#
|
56
|
+
def self.log_execution_error(worker, error)
|
57
|
+
# ActiveJob has its own error logging. No need to double log the error.
|
58
|
+
# Note: we use string matching instead of class matching as
|
59
|
+
# ActiveJob::QueueAdapters::CloudtaskerAdapter::JobWrapper might not be loaded
|
60
|
+
return if worker.class.to_s =~ /^ActiveJob::/
|
61
|
+
|
62
|
+
# Choose logger to use based on context
|
63
|
+
# Worker will be nil on InvalidWorkerError - in that case we use generic logging
|
64
|
+
logger = worker&.logger || Cloudtasker.logger
|
65
|
+
|
66
|
+
# Log error
|
67
|
+
logger.error(error)
|
68
|
+
end
|
69
|
+
|
48
70
|
#
|
49
71
|
# Execute a task worker from a task payload
|
50
72
|
#
|
@@ -88,6 +110,10 @@ module Cloudtasker
|
|
88
110
|
rescue DeadWorkerError, MissingWorkerArgumentsError => e
|
89
111
|
# Delete stored args payload if job is dead
|
90
112
|
redis.expire(args_payload_key, ARGS_PAYLOAD_CLEANUP_TTL) if args_payload_key
|
113
|
+
log_execution_error(worker, e)
|
114
|
+
raise(e)
|
115
|
+
rescue StandardError => e
|
116
|
+
log_execution_error(worker, e)
|
91
117
|
raise(e)
|
92
118
|
end
|
93
119
|
|
@@ -51,6 +51,26 @@ module Cloudtasker
|
|
51
51
|
Cloudtasker.logger
|
52
52
|
end
|
53
53
|
|
54
|
+
#
|
55
|
+
# Format the log message as string.
|
56
|
+
#
|
57
|
+
# @param [Object] msg The log message or object.
|
58
|
+
#
|
59
|
+
# @return [String] The formatted message
|
60
|
+
#
|
61
|
+
def formatted_message_as_string(msg)
|
62
|
+
# Format message
|
63
|
+
msg_content = if msg.is_a?(Exception)
|
64
|
+
[msg.inspect, msg.backtrace].flatten(1).join("\n")
|
65
|
+
elsif msg.is_a?(String)
|
66
|
+
msg
|
67
|
+
else
|
68
|
+
msg.inspect
|
69
|
+
end
|
70
|
+
|
71
|
+
"[Cloudtasker][#{worker.class}][#{worker.job_id}] #{msg_content}"
|
72
|
+
end
|
73
|
+
|
54
74
|
#
|
55
75
|
# Format main log message.
|
56
76
|
#
|
@@ -59,7 +79,12 @@ module Cloudtasker
|
|
59
79
|
# @return [String] The formatted log message
|
60
80
|
#
|
61
81
|
def formatted_message(msg)
|
62
|
-
|
82
|
+
if msg.is_a?(String)
|
83
|
+
formatted_message_as_string(msg)
|
84
|
+
else
|
85
|
+
# Delegate object formatting to logger
|
86
|
+
msg
|
87
|
+
end
|
63
88
|
end
|
64
89
|
|
65
90
|
#
|
@@ -147,7 +172,9 @@ module Cloudtasker
|
|
147
172
|
# ActiveSupport::Logger does not support passing a payload through a block on top
|
148
173
|
# of a message.
|
149
174
|
if defined?(ActiveSupport::Logger) && logger.is_a?(ActiveSupport::Logger)
|
150
|
-
logger
|
175
|
+
# The logger is fairly basic in terms of formatting. All inputs get converted
|
176
|
+
# as regular strings.
|
177
|
+
logger.send(level) { "#{formatted_message_as_string(msg)} -- #{payload_block.call}" }
|
151
178
|
else
|
152
179
|
logger.send(level, formatted_message(msg), &payload_block)
|
153
180
|
end
|
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.
|
4
|
+
version: 0.12.rc5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Arnaud Lachaume
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-03-
|
11
|
+
date: 2021-03-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -427,9 +427,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
427
427
|
version: '0'
|
428
428
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
429
429
|
requirements:
|
430
|
-
- - "
|
430
|
+
- - ">"
|
431
431
|
- !ruby/object:Gem::Version
|
432
|
-
version:
|
432
|
+
version: 1.3.1
|
433
433
|
requirements: []
|
434
434
|
rubygems_version: 3.0.0
|
435
435
|
signing_key:
|