cloudtasker 0.11.0 → 0.12.rc5
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/.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:
|