cloudtasker 0.13.1 → 0.14.rc1
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/lint_rubocop.yml +1 -1
- data/.github/workflows/test_ruby_3.x.yml +1 -0
- data/.gitignore +4 -1
- data/.rubocop.yml +37 -9
- data/Appraisals +0 -12
- data/CHANGELOG.md +31 -0
- data/Gemfile +12 -0
- data/README.md +145 -6
- data/app/controllers/cloudtasker/worker_controller.rb +30 -9
- data/cloudtasker.gemspec +3 -10
- data/docs/CRON_JOBS.md +23 -0
- data/docs/STORABLE_JOBS.md +68 -0
- data/exe/cloudtasker +5 -2
- data/gemfiles/google_cloud_tasks_1.0.gemfile +10 -1
- data/gemfiles/google_cloud_tasks_1.1.gemfile +10 -1
- data/gemfiles/google_cloud_tasks_1.2.gemfile +10 -1
- data/gemfiles/google_cloud_tasks_1.3.gemfile +10 -1
- data/gemfiles/google_cloud_tasks_1.4.gemfile +10 -1
- data/gemfiles/google_cloud_tasks_1.5.gemfile +10 -1
- data/gemfiles/google_cloud_tasks_2.0.gemfile +10 -1
- data/gemfiles/google_cloud_tasks_2.1.gemfile +10 -1
- data/gemfiles/rails_5.2.gemfile +10 -0
- data/gemfiles/rails_6.0.gemfile +10 -0
- data/gemfiles/rails_6.1.gemfile +10 -0
- data/gemfiles/rails_7.0.gemfile +10 -0
- data/gemfiles/semantic_logger_3.4.gemfile +9 -1
- data/gemfiles/semantic_logger_4.6.gemfile +9 -1
- data/gemfiles/semantic_logger_4.7.0.gemfile +9 -1
- data/gemfiles/semantic_logger_4.7.2.gemfile +9 -1
- data/lib/active_job/queue_adapters/cloudtasker_adapter.rb +8 -1
- data/lib/cloudtasker/authenticator.rb +35 -0
- data/lib/cloudtasker/backend/google_cloud_task_v1.rb +2 -4
- data/lib/cloudtasker/backend/google_cloud_task_v2.rb +3 -5
- data/lib/cloudtasker/backend/memory_task.rb +8 -4
- data/lib/cloudtasker/backend/redis_task.rb +10 -4
- data/lib/cloudtasker/batch/batch_progress.rb +18 -14
- data/lib/cloudtasker/batch/job.rb +124 -31
- data/lib/cloudtasker/batch/middleware/server.rb +2 -2
- data/lib/cloudtasker/cli.rb +5 -7
- data/lib/cloudtasker/cloud_task.rb +16 -20
- data/lib/cloudtasker/config.rb +43 -10
- data/lib/cloudtasker/cron/middleware/server.rb +2 -2
- data/lib/cloudtasker/cron/schedule.rb +5 -2
- data/lib/cloudtasker/middleware/chain.rb +1 -1
- data/lib/cloudtasker/redis_client.rb +1 -4
- data/lib/cloudtasker/retry_worker_error.rb +6 -0
- data/lib/cloudtasker/storable/worker.rb +78 -0
- data/lib/cloudtasker/storable.rb +3 -0
- data/lib/cloudtasker/unique_job/conflict_strategy/base_strategy.rb +4 -2
- data/lib/cloudtasker/unique_job/lock/until_executed.rb +4 -4
- data/lib/cloudtasker/unique_job/lock/until_executing.rb +2 -2
- data/lib/cloudtasker/unique_job/lock/while_executing.rb +2 -2
- data/lib/cloudtasker/unique_job/middleware/client.rb +2 -2
- data/lib/cloudtasker/unique_job/middleware/server.rb +2 -2
- data/lib/cloudtasker/version.rb +1 -1
- data/lib/cloudtasker/worker.rb +38 -15
- data/lib/cloudtasker/worker_handler.rb +25 -19
- data/lib/cloudtasker/worker_logger.rb +48 -0
- data/lib/cloudtasker.rb +4 -1
- data/lib/tasks/setup_queue.rake +6 -6
- metadata +9 -145
- data/.github/workflows/test_ruby_2.6.yml +0 -37
@@ -10,11 +10,11 @@ module Cloudtasker
|
|
10
10
|
# Acquire a lock for the job and trigger a conflict
|
11
11
|
# if the lock could not be acquired.
|
12
12
|
#
|
13
|
-
def schedule
|
13
|
+
def schedule(&block)
|
14
14
|
job.lock!
|
15
15
|
yield
|
16
16
|
rescue LockError
|
17
|
-
conflict_instance.on_schedule
|
17
|
+
conflict_instance.on_schedule(&block)
|
18
18
|
end
|
19
19
|
|
20
20
|
#
|
@@ -10,11 +10,11 @@ module Cloudtasker
|
|
10
10
|
# Acquire a lock for the job and trigger a conflict
|
11
11
|
# if the lock could not be acquired.
|
12
12
|
#
|
13
|
-
def execute
|
13
|
+
def execute(&block)
|
14
14
|
job.lock!
|
15
15
|
yield
|
16
16
|
rescue LockError
|
17
|
-
conflict_instance.on_execute
|
17
|
+
conflict_instance.on_execute(&block)
|
18
18
|
ensure
|
19
19
|
# Unlock the job on any error to avoid deadlocks.
|
20
20
|
job.unlock!
|
@@ -6,8 +6,8 @@ module Cloudtasker
|
|
6
6
|
# TODO: kwargs to job otherwise it won't get the time_at
|
7
7
|
# Client middleware, invoked when jobs are scheduled
|
8
8
|
class Client
|
9
|
-
def call(worker, _opts = {})
|
10
|
-
Job.new(worker).lock_instance.schedule
|
9
|
+
def call(worker, _opts = {}, &block)
|
10
|
+
Job.new(worker).lock_instance.schedule(&block)
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
@@ -5,8 +5,8 @@ module Cloudtasker
|
|
5
5
|
module Middleware
|
6
6
|
# Server middleware, invoked when jobs are executed
|
7
7
|
class Server
|
8
|
-
def call(worker, **_kwargs)
|
9
|
-
Job.new(worker).lock_instance.execute
|
8
|
+
def call(worker, **_kwargs, &block)
|
9
|
+
Job.new(worker).lock_instance.execute(&block)
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
data/lib/cloudtasker/version.rb
CHANGED
data/lib/cloudtasker/worker.rb
CHANGED
@@ -54,6 +54,15 @@ module Cloudtasker
|
|
54
54
|
|
55
55
|
# Module class methods
|
56
56
|
module ClassMethods
|
57
|
+
#
|
58
|
+
# Return the Cloudtasker redis client
|
59
|
+
#
|
60
|
+
# @return [Cloudtasker::RedisClient] The cloudtasker redis client.
|
61
|
+
#
|
62
|
+
def redis
|
63
|
+
@redis ||= RedisClient.new
|
64
|
+
end
|
65
|
+
|
57
66
|
#
|
58
67
|
# Set the worker runtime options.
|
59
68
|
#
|
@@ -63,7 +72,7 @@ module Cloudtasker
|
|
63
72
|
#
|
64
73
|
def cloudtasker_options(opts = {})
|
65
74
|
opt_list = opts&.map { |k, v| [k.to_sym, v] } || [] # symbolize
|
66
|
-
@cloudtasker_options_hash =
|
75
|
+
@cloudtasker_options_hash = opt_list.to_h
|
67
76
|
end
|
68
77
|
|
69
78
|
#
|
@@ -75,6 +84,17 @@ module Cloudtasker
|
|
75
84
|
@cloudtasker_options_hash || {}
|
76
85
|
end
|
77
86
|
|
87
|
+
#
|
88
|
+
# Return a namespaced cache key.
|
89
|
+
#
|
90
|
+
# @param [Any, Array<Any>, nil] val The key to namespace
|
91
|
+
#
|
92
|
+
# @return [String] The namespaced key(s).
|
93
|
+
#
|
94
|
+
def cache_key(val = nil)
|
95
|
+
[to_s.underscore, val].flatten.compact.map(&:to_s).join('/')
|
96
|
+
end
|
97
|
+
|
78
98
|
#
|
79
99
|
# Enqueue worker in the backgroundf.
|
80
100
|
#
|
@@ -174,13 +194,13 @@ module Cloudtasker
|
|
174
194
|
# @return [Integer] The value in seconds.
|
175
195
|
#
|
176
196
|
def dispatch_deadline
|
177
|
-
@dispatch_deadline ||=
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
Config::MAX_DISPATCH_DEADLINE
|
183
|
-
|
197
|
+
@dispatch_deadline ||= begin
|
198
|
+
configured_deadline = (
|
199
|
+
self.class.cloudtasker_options_hash[:dispatch_deadline] ||
|
200
|
+
Cloudtasker.config.dispatch_deadline
|
201
|
+
).to_i
|
202
|
+
configured_deadline.clamp(Config::MIN_DISPATCH_DEADLINE, Config::MAX_DISPATCH_DEADLINE)
|
203
|
+
end
|
184
204
|
end
|
185
205
|
|
186
206
|
#
|
@@ -204,13 +224,16 @@ module Cloudtasker
|
|
204
224
|
resp = execute_middleware_chain
|
205
225
|
|
206
226
|
# Log job completion and return result
|
207
|
-
logger.info("Job done after #{job_duration}s") { { duration: job_duration } }
|
227
|
+
logger.info("Job done after #{job_duration}s") { { duration: job_duration * 1000 } }
|
208
228
|
resp
|
209
229
|
rescue DeadWorkerError => e
|
210
|
-
logger.info("Job dead after #{job_duration}s and #{job_retries} retries") { { duration: job_duration } }
|
230
|
+
logger.info("Job dead after #{job_duration}s and #{job_retries} retries") { { duration: job_duration * 1000 } }
|
231
|
+
raise(e)
|
232
|
+
rescue RetryWorkerError => e
|
233
|
+
logger.info("Job done after #{job_duration}s (retry requested)") { { duration: job_duration * 1000 } }
|
211
234
|
raise(e)
|
212
235
|
rescue StandardError => e
|
213
|
-
logger.info("Job failed after #{job_duration}s") { { duration: job_duration } }
|
236
|
+
logger.info("Job failed after #{job_duration}s") { { duration: job_duration * 1000 } }
|
214
237
|
raise(e)
|
215
238
|
end
|
216
239
|
|
@@ -235,7 +258,7 @@ module Cloudtasker
|
|
235
258
|
# @param [Integer] interval The delay in seconds.
|
236
259
|
# @param [Time, Integer] interval The time at which the job should run
|
237
260
|
#
|
238
|
-
# @return [Cloudtasker::CloudTask] The Google Task response
|
261
|
+
# @return [Cloudtasker::CloudTask, nil] The Google Task response or nil if the job was not scheduled
|
239
262
|
#
|
240
263
|
def schedule(**args)
|
241
264
|
# Evaluate when to schedule the job
|
@@ -323,7 +346,7 @@ module Cloudtasker
|
|
323
346
|
# @return [Integer] The number of retries
|
324
347
|
#
|
325
348
|
def job_max_retries
|
326
|
-
@job_max_retries ||=
|
349
|
+
@job_max_retries ||= try(:max_retries, *job_args) || self.class.max_retries
|
327
350
|
end
|
328
351
|
|
329
352
|
#
|
@@ -373,7 +396,7 @@ module Cloudtasker
|
|
373
396
|
def job_duration
|
374
397
|
return 0.0 unless perform_ended_at && perform_started_at
|
375
398
|
|
376
|
-
(perform_ended_at - perform_started_at).ceil(3)
|
399
|
+
@job_duration ||= (perform_ended_at - perform_started_at).ceil(3)
|
377
400
|
end
|
378
401
|
|
379
402
|
#
|
@@ -422,7 +445,7 @@ module Cloudtasker
|
|
422
445
|
# Perform the job
|
423
446
|
perform(*job_args)
|
424
447
|
rescue StandardError => e
|
425
|
-
run_callback(:on_error, e)
|
448
|
+
run_callback(:on_error, e) unless e.is_a?(RetryWorkerError)
|
426
449
|
return raise(e) unless job_must_die?
|
427
450
|
|
428
451
|
# Flag job as dead
|
@@ -53,6 +53,9 @@ module Cloudtasker
|
|
53
53
|
# ActiveJob::QueueAdapters::CloudtaskerAdapter::JobWrapper might not be loaded
|
54
54
|
return if worker.class.to_s =~ /^ActiveJob::/
|
55
55
|
|
56
|
+
# Do not log error when a retry was specifically requested
|
57
|
+
return if error.is_a?(RetryWorkerError)
|
58
|
+
|
56
59
|
# Choose logger to use based on context
|
57
60
|
# Worker will be nil on InvalidWorkerError - in that case we use generic logging
|
58
61
|
logger = worker&.logger || Cloudtasker.logger
|
@@ -148,16 +151,21 @@ module Cloudtasker
|
|
148
151
|
# @return [Hash] The task body
|
149
152
|
#
|
150
153
|
def task_payload
|
154
|
+
# Generate content
|
155
|
+
worker_payload_json = worker_payload.to_json
|
156
|
+
|
157
|
+
# Build payload
|
151
158
|
{
|
152
159
|
http_request: {
|
153
160
|
http_method: 'POST',
|
154
161
|
url: Cloudtasker.config.processor_url,
|
155
162
|
headers: {
|
156
163
|
Cloudtasker::Config::CONTENT_TYPE_HEADER => 'application/json',
|
157
|
-
Cloudtasker::Config::
|
158
|
-
},
|
159
|
-
|
160
|
-
|
164
|
+
Cloudtasker::Config::CT_SIGNATURE_HEADER => Authenticator.sign_payload(worker_payload_json)
|
165
|
+
}.compact,
|
166
|
+
oidc_token: Cloudtasker.config.oidc,
|
167
|
+
body: worker_payload_json
|
168
|
+
}.compact,
|
161
169
|
dispatch_deadline: worker.dispatch_deadline.to_i,
|
162
170
|
queue: worker.job_queue
|
163
171
|
}
|
@@ -187,21 +195,19 @@ module Cloudtasker
|
|
187
195
|
# @return [Hash] The worker args payload.
|
188
196
|
#
|
189
197
|
def worker_args_payload
|
190
|
-
@worker_args_payload ||=
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
end
|
204
|
-
end
|
198
|
+
@worker_args_payload ||= if store_payload_in_redis?
|
199
|
+
# Store payload in Redis
|
200
|
+
self.class.redis.write(
|
201
|
+
self.class.key([REDIS_PAYLOAD_NAMESPACE, worker.job_id].join('/')),
|
202
|
+
worker.job_args
|
203
|
+
)
|
204
|
+
|
205
|
+
# Return reference to args payload
|
206
|
+
{ job_args_payload_id: worker.job_id }
|
207
|
+
else
|
208
|
+
# Return regular job args payload
|
209
|
+
{ job_args: worker.job_args }
|
210
|
+
end
|
205
211
|
end
|
206
212
|
|
207
213
|
#
|
@@ -8,6 +8,54 @@ module Cloudtasker
|
|
8
8
|
|
9
9
|
class << self
|
10
10
|
attr_accessor :log_context_processor
|
11
|
+
|
12
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
13
|
+
#
|
14
|
+
# Truncate an array or hash payload.
|
15
|
+
#
|
16
|
+
# This can be used to log arguments on jobs while still keeping logs to a
|
17
|
+
# reasonable size.
|
18
|
+
#
|
19
|
+
# @param [Hash,Array] payload The payload to truncate
|
20
|
+
# @param [Integer] string_limit The maximum size for strings. Set to -1 to disable.
|
21
|
+
# @param [Integer] array_limit The maximum length for arrays. Set to -1 to disable.
|
22
|
+
# @param [Hash] max_depth The maximum recursive depth. Set to -1 to disable.
|
23
|
+
#
|
24
|
+
# @return [Hash,Array] The truncated payload
|
25
|
+
#
|
26
|
+
def truncate(payload, **kwargs)
|
27
|
+
depth = kwargs[:depth].to_i
|
28
|
+
max_depth = kwargs[:max_depth] || 3
|
29
|
+
string_limit = kwargs[:string_limit] || 64
|
30
|
+
array_limit = kwargs[:array_limit] || 10
|
31
|
+
|
32
|
+
case payload
|
33
|
+
when Array
|
34
|
+
if max_depth > -1 && depth > max_depth
|
35
|
+
["...#{payload.size} items..."]
|
36
|
+
elsif array_limit > -1
|
37
|
+
payload.take(array_limit).map { |e| truncate(e, **kwargs, depth: depth + 1) } +
|
38
|
+
(payload.size > array_limit ? ["...#{payload.size - array_limit} items..."] : [])
|
39
|
+
else
|
40
|
+
payload.map { |e| truncate(e, **kwargs, depth: depth + 1) }
|
41
|
+
end
|
42
|
+
when Hash
|
43
|
+
if max_depth > -1 && depth > max_depth
|
44
|
+
'{hash}'
|
45
|
+
else
|
46
|
+
payload.transform_values { |e| truncate(e, **kwargs, depth: depth + 1) }
|
47
|
+
end
|
48
|
+
when String
|
49
|
+
if string_limit > -1 && payload.size > string_limit
|
50
|
+
payload.truncate(string_limit)
|
51
|
+
else
|
52
|
+
payload
|
53
|
+
end
|
54
|
+
else
|
55
|
+
payload
|
56
|
+
end
|
57
|
+
end
|
58
|
+
# rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
|
11
59
|
end
|
12
60
|
|
13
61
|
# Only log the job meta information by default (exclude arguments)
|
data/lib/cloudtasker.rb
CHANGED
@@ -3,12 +3,15 @@
|
|
3
3
|
require 'active_support/core_ext/object/blank'
|
4
4
|
require 'active_support/core_ext/object/try'
|
5
5
|
require 'active_support/core_ext/string/inflections'
|
6
|
+
require 'active_support/core_ext/string/filters'
|
7
|
+
require 'active_support/security_utils'
|
6
8
|
|
7
9
|
require 'cloudtasker/version'
|
8
10
|
require 'cloudtasker/config'
|
9
11
|
|
10
12
|
require 'cloudtasker/authentication_error'
|
11
13
|
require 'cloudtasker/dead_worker_error'
|
14
|
+
require 'cloudtasker/retry_worker_error'
|
12
15
|
require 'cloudtasker/invalid_worker_error'
|
13
16
|
require 'cloudtasker/missing_worker_arguments_error'
|
14
17
|
require 'cloudtasker/max_task_size_exceeded_error'
|
@@ -51,4 +54,4 @@ module Cloudtasker
|
|
51
54
|
end
|
52
55
|
end
|
53
56
|
|
54
|
-
require 'cloudtasker/engine' if defined?(
|
57
|
+
require 'cloudtasker/engine' if defined?(Rails::Engine)
|
data/lib/tasks/setup_queue.rake
CHANGED
@@ -7,14 +7,14 @@ ENV['GOOGLE_AUTH_SUPPRESS_CREDENTIALS_WARNINGS'] ||= 'true'
|
|
7
7
|
|
8
8
|
namespace :cloudtasker do
|
9
9
|
desc 'Setup a Cloud Task queue. (default options: ' \
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
"name=#{Cloudtasker::Config::DEFAULT_JOB_QUEUE}, " \
|
11
|
+
"concurrency=#{Cloudtasker::Config::DEFAULT_QUEUE_CONCURRENCY}, " \
|
12
|
+
"retries=#{Cloudtasker::Config::DEFAULT_QUEUE_RETRIES})"
|
13
13
|
task setup_queue: :environment do
|
14
14
|
puts Cloudtasker::CloudTask.setup_production_queue(
|
15
|
-
name: ENV
|
16
|
-
concurrency: ENV
|
17
|
-
retries: ENV
|
15
|
+
name: ENV.fetch('name', nil),
|
16
|
+
concurrency: ENV.fetch('concurrency', nil),
|
17
|
+
retries: ENV.fetch('retries', nil)
|
18
18
|
)
|
19
19
|
end
|
20
20
|
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.14.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Arnaud Lachaume
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-09-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -108,146 +108,6 @@ dependencies:
|
|
108
108
|
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: appraisal
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - ">="
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: '0'
|
118
|
-
type: :development
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - ">="
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: '0'
|
125
|
-
- !ruby/object:Gem::Dependency
|
126
|
-
name: bundler
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - "~>"
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version: '2.0'
|
132
|
-
type: :development
|
133
|
-
prerelease: false
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
135
|
-
requirements:
|
136
|
-
- - "~>"
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: '2.0'
|
139
|
-
- !ruby/object:Gem::Dependency
|
140
|
-
name: rake
|
141
|
-
requirement: !ruby/object:Gem::Requirement
|
142
|
-
requirements:
|
143
|
-
- - ">="
|
144
|
-
- !ruby/object:Gem::Version
|
145
|
-
version: 12.3.3
|
146
|
-
type: :development
|
147
|
-
prerelease: false
|
148
|
-
version_requirements: !ruby/object:Gem::Requirement
|
149
|
-
requirements:
|
150
|
-
- - ">="
|
151
|
-
- !ruby/object:Gem::Version
|
152
|
-
version: 12.3.3
|
153
|
-
- !ruby/object:Gem::Dependency
|
154
|
-
name: rspec
|
155
|
-
requirement: !ruby/object:Gem::Requirement
|
156
|
-
requirements:
|
157
|
-
- - "~>"
|
158
|
-
- !ruby/object:Gem::Version
|
159
|
-
version: '3.0'
|
160
|
-
type: :development
|
161
|
-
prerelease: false
|
162
|
-
version_requirements: !ruby/object:Gem::Requirement
|
163
|
-
requirements:
|
164
|
-
- - "~>"
|
165
|
-
- !ruby/object:Gem::Version
|
166
|
-
version: '3.0'
|
167
|
-
- !ruby/object:Gem::Dependency
|
168
|
-
name: rspec-json_expectations
|
169
|
-
requirement: !ruby/object:Gem::Requirement
|
170
|
-
requirements:
|
171
|
-
- - "~>"
|
172
|
-
- !ruby/object:Gem::Version
|
173
|
-
version: '2.2'
|
174
|
-
type: :development
|
175
|
-
prerelease: false
|
176
|
-
version_requirements: !ruby/object:Gem::Requirement
|
177
|
-
requirements:
|
178
|
-
- - "~>"
|
179
|
-
- !ruby/object:Gem::Version
|
180
|
-
version: '2.2'
|
181
|
-
- !ruby/object:Gem::Dependency
|
182
|
-
name: rubocop
|
183
|
-
requirement: !ruby/object:Gem::Requirement
|
184
|
-
requirements:
|
185
|
-
- - '='
|
186
|
-
- !ruby/object:Gem::Version
|
187
|
-
version: 0.76.0
|
188
|
-
type: :development
|
189
|
-
prerelease: false
|
190
|
-
version_requirements: !ruby/object:Gem::Requirement
|
191
|
-
requirements:
|
192
|
-
- - '='
|
193
|
-
- !ruby/object:Gem::Version
|
194
|
-
version: 0.76.0
|
195
|
-
- !ruby/object:Gem::Dependency
|
196
|
-
name: rubocop-rspec
|
197
|
-
requirement: !ruby/object:Gem::Requirement
|
198
|
-
requirements:
|
199
|
-
- - '='
|
200
|
-
- !ruby/object:Gem::Version
|
201
|
-
version: 1.37.0
|
202
|
-
type: :development
|
203
|
-
prerelease: false
|
204
|
-
version_requirements: !ruby/object:Gem::Requirement
|
205
|
-
requirements:
|
206
|
-
- - '='
|
207
|
-
- !ruby/object:Gem::Version
|
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'
|
223
|
-
- !ruby/object:Gem::Dependency
|
224
|
-
name: timecop
|
225
|
-
requirement: !ruby/object:Gem::Requirement
|
226
|
-
requirements:
|
227
|
-
- - ">="
|
228
|
-
- !ruby/object:Gem::Version
|
229
|
-
version: '0'
|
230
|
-
type: :development
|
231
|
-
prerelease: false
|
232
|
-
version_requirements: !ruby/object:Gem::Requirement
|
233
|
-
requirements:
|
234
|
-
- - ">="
|
235
|
-
- !ruby/object:Gem::Version
|
236
|
-
version: '0'
|
237
|
-
- !ruby/object:Gem::Dependency
|
238
|
-
name: webmock
|
239
|
-
requirement: !ruby/object:Gem::Requirement
|
240
|
-
requirements:
|
241
|
-
- - ">="
|
242
|
-
- !ruby/object:Gem::Version
|
243
|
-
version: '0'
|
244
|
-
type: :development
|
245
|
-
prerelease: false
|
246
|
-
version_requirements: !ruby/object:Gem::Requirement
|
247
|
-
requirements:
|
248
|
-
- - ">="
|
249
|
-
- !ruby/object:Gem::Version
|
250
|
-
version: '0'
|
251
111
|
description: Background jobs for Ruby using Google Cloud Tasks (beta)
|
252
112
|
email:
|
253
113
|
- arnaud.lachaume@keypup.io
|
@@ -257,7 +117,6 @@ extensions: []
|
|
257
117
|
extra_rdoc_files: []
|
258
118
|
files:
|
259
119
|
- ".github/workflows/lint_rubocop.yml"
|
260
|
-
- ".github/workflows/test_ruby_2.6.yml"
|
261
120
|
- ".github/workflows/test_ruby_2.7.yml"
|
262
121
|
- ".github/workflows/test_ruby_3.x.yml"
|
263
122
|
- ".gitignore"
|
@@ -278,6 +137,7 @@ files:
|
|
278
137
|
- config/routes.rb
|
279
138
|
- docs/BATCH_JOBS.md
|
280
139
|
- docs/CRON_JOBS.md
|
140
|
+
- docs/STORABLE_JOBS.md
|
281
141
|
- docs/UNIQUE_JOBS.md
|
282
142
|
- exe/cloudtasker
|
283
143
|
- gemfiles/.bundle/config
|
@@ -328,6 +188,9 @@ files:
|
|
328
188
|
- lib/cloudtasker/middleware/chain.rb
|
329
189
|
- lib/cloudtasker/missing_worker_arguments_error.rb
|
330
190
|
- lib/cloudtasker/redis_client.rb
|
191
|
+
- lib/cloudtasker/retry_worker_error.rb
|
192
|
+
- lib/cloudtasker/storable.rb
|
193
|
+
- lib/cloudtasker/storable/worker.rb
|
331
194
|
- lib/cloudtasker/testing.rb
|
332
195
|
- lib/cloudtasker/unique_job.rb
|
333
196
|
- lib/cloudtasker/unique_job/conflict_strategy/base_strategy.rb
|
@@ -357,6 +220,7 @@ metadata:
|
|
357
220
|
homepage_uri: https://github.com/keypup-io/cloudtasker
|
358
221
|
source_code_uri: https://github.com/keypup-io/cloudtasker
|
359
222
|
changelog_uri: https://github.com/keypup-io/cloudtasker/master/tree/CHANGELOG.md
|
223
|
+
rubygems_mfa_required: 'true'
|
360
224
|
post_install_message:
|
361
225
|
rdoc_options: []
|
362
226
|
require_paths:
|
@@ -365,14 +229,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
365
229
|
requirements:
|
366
230
|
- - ">="
|
367
231
|
- !ruby/object:Gem::Version
|
368
|
-
version:
|
232
|
+
version: 2.7.0
|
369
233
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
370
234
|
requirements:
|
371
235
|
- - ">="
|
372
236
|
- !ruby/object:Gem::Version
|
373
237
|
version: '0'
|
374
238
|
requirements: []
|
375
|
-
rubygems_version: 3.4
|
239
|
+
rubygems_version: 3.5.4
|
376
240
|
signing_key:
|
377
241
|
specification_version: 4
|
378
242
|
summary: Background jobs for Ruby using Google Cloud Tasks (beta)
|
@@ -1,37 +0,0 @@
|
|
1
|
-
name: Ruby 2.6
|
2
|
-
|
3
|
-
on: [push, pull_request]
|
4
|
-
|
5
|
-
jobs:
|
6
|
-
build:
|
7
|
-
runs-on: ubuntu-latest
|
8
|
-
strategy:
|
9
|
-
matrix:
|
10
|
-
ruby:
|
11
|
-
- '2.6'
|
12
|
-
appraisal:
|
13
|
-
- 'google_cloud_tasks_1.0'
|
14
|
-
- 'google_cloud_tasks_1.1'
|
15
|
-
- 'google_cloud_tasks_1.2'
|
16
|
-
- 'google_cloud_tasks_1.3'
|
17
|
-
- 'google_cloud_tasks_1.4'
|
18
|
-
- 'google_cloud_tasks_1.5'
|
19
|
-
- 'google_cloud_tasks_2.0'
|
20
|
-
- 'google_cloud_tasks_2.1'
|
21
|
-
- 'rails_5.2'
|
22
|
-
- 'rails_6.0'
|
23
|
-
- 'rails_6.1'
|
24
|
-
- 'semantic_logger_3.4'
|
25
|
-
- 'semantic_logger_4.6'
|
26
|
-
- 'semantic_logger_4.7.0'
|
27
|
-
- 'semantic_logger_4.7.2'
|
28
|
-
env:
|
29
|
-
BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.appraisal }}.gemfile
|
30
|
-
steps:
|
31
|
-
- uses: actions/checkout@v2
|
32
|
-
- uses: zhulik/redis-action@1.1.0
|
33
|
-
- uses: ruby/setup-ruby@v1
|
34
|
-
with:
|
35
|
-
ruby-version: ${{ matrix.ruby }}
|
36
|
-
bundler-cache: true
|
37
|
-
- run: bundle exec rspec
|