cloudtasker 0.1.0
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 +7 -0
- data/.gitignore +12 -0
- data/.rspec +3 -0
- data/.rubocop.yml +27 -0
- data/.travis.yml +7 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +247 -0
- data/LICENSE.txt +21 -0
- data/README.md +43 -0
- data/Rakefile +8 -0
- data/app/controllers/cloudtasker/application_controller.rb +6 -0
- data/app/controllers/cloudtasker/worker_controller.rb +38 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/cloudtasker.gemspec +48 -0
- data/config/routes.rb +5 -0
- data/lib/cloudtasker.rb +31 -0
- data/lib/cloudtasker/authentication_error.rb +6 -0
- data/lib/cloudtasker/authenticator.rb +55 -0
- data/lib/cloudtasker/batch.rb +5 -0
- data/lib/cloudtasker/batch/batch_progress.rb +97 -0
- data/lib/cloudtasker/batch/config.rb +11 -0
- data/lib/cloudtasker/batch/extension/worker.rb +13 -0
- data/lib/cloudtasker/batch/job.rb +320 -0
- data/lib/cloudtasker/batch/middleware.rb +24 -0
- data/lib/cloudtasker/batch/middleware/server.rb +14 -0
- data/lib/cloudtasker/config.rb +122 -0
- data/lib/cloudtasker/cron.rb +5 -0
- data/lib/cloudtasker/cron/config.rb +11 -0
- data/lib/cloudtasker/cron/job.rb +207 -0
- data/lib/cloudtasker/cron/middleware.rb +21 -0
- data/lib/cloudtasker/cron/middleware/server.rb +14 -0
- data/lib/cloudtasker/cron/schedule.rb +227 -0
- data/lib/cloudtasker/engine.rb +20 -0
- data/lib/cloudtasker/invalid_worker_error.rb +6 -0
- data/lib/cloudtasker/meta_store.rb +86 -0
- data/lib/cloudtasker/middleware/chain.rb +250 -0
- data/lib/cloudtasker/redis_client.rb +115 -0
- data/lib/cloudtasker/task.rb +175 -0
- data/lib/cloudtasker/unique_job.rb +5 -0
- data/lib/cloudtasker/unique_job/config.rb +10 -0
- data/lib/cloudtasker/unique_job/conflict_strategy/base_strategy.rb +37 -0
- data/lib/cloudtasker/unique_job/conflict_strategy/raise.rb +28 -0
- data/lib/cloudtasker/unique_job/conflict_strategy/reject.rb +11 -0
- data/lib/cloudtasker/unique_job/conflict_strategy/reschedule.rb +30 -0
- data/lib/cloudtasker/unique_job/job.rb +136 -0
- data/lib/cloudtasker/unique_job/lock/base_lock.rb +70 -0
- data/lib/cloudtasker/unique_job/lock/no_op.rb +11 -0
- data/lib/cloudtasker/unique_job/lock/until_executed.rb +34 -0
- data/lib/cloudtasker/unique_job/lock/until_executing.rb +30 -0
- data/lib/cloudtasker/unique_job/lock/while_executing.rb +23 -0
- data/lib/cloudtasker/unique_job/lock_error.rb +8 -0
- data/lib/cloudtasker/unique_job/middleware.rb +36 -0
- data/lib/cloudtasker/unique_job/middleware/client.rb +14 -0
- data/lib/cloudtasker/unique_job/middleware/server.rb +14 -0
- data/lib/cloudtasker/version.rb +5 -0
- data/lib/cloudtasker/worker.rb +211 -0
- metadata +286 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Cloudtasker
|
4
|
+
module UniqueJob
|
5
|
+
module Lock
|
6
|
+
# Conflict if any other job with the same args is scheduled or moved to execution
|
7
|
+
# while the first job is pending or executing.
|
8
|
+
class UntilExecuted < BaseLock
|
9
|
+
#
|
10
|
+
# Acquire a lock for the job and trigger a conflict
|
11
|
+
# if the lock could not be acquired.
|
12
|
+
#
|
13
|
+
def schedule
|
14
|
+
job.lock!
|
15
|
+
yield
|
16
|
+
rescue LockError
|
17
|
+
conflict_instance.on_schedule { yield }
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
# Acquire a lock for the job and trigger a conflict
|
22
|
+
# if the lock could not be acquired.
|
23
|
+
#
|
24
|
+
def execute
|
25
|
+
job.lock!
|
26
|
+
yield
|
27
|
+
job.unlock!
|
28
|
+
rescue LockError
|
29
|
+
conflict_instance.on_execute { yield }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Cloudtasker
|
4
|
+
module UniqueJob
|
5
|
+
module Lock
|
6
|
+
# Conflict if any other job with the same args is scheduled
|
7
|
+
# while the first job is pending.
|
8
|
+
class UntilExecuting < BaseLock
|
9
|
+
#
|
10
|
+
# Acquire a lock for the job and trigger a conflict
|
11
|
+
# if the lock could not be acquired.
|
12
|
+
#
|
13
|
+
def schedule
|
14
|
+
job.lock!
|
15
|
+
yield
|
16
|
+
rescue LockError
|
17
|
+
conflict_instance.on_schedule { yield }
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
# Release the lock and perform the job.
|
22
|
+
#
|
23
|
+
def execute
|
24
|
+
job.unlock!
|
25
|
+
yield
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Cloudtasker
|
4
|
+
module UniqueJob
|
5
|
+
module Lock
|
6
|
+
# Conflict if any other job with the same args is moved to execution
|
7
|
+
# while the first job is executing.
|
8
|
+
class WhileExecuting < BaseLock
|
9
|
+
#
|
10
|
+
# Acquire a lock for the job and trigger a conflict
|
11
|
+
# if the lock could not be acquired.
|
12
|
+
#
|
13
|
+
def execute
|
14
|
+
job.lock!
|
15
|
+
yield
|
16
|
+
job.unlock!
|
17
|
+
rescue LockError
|
18
|
+
conflict_instance.on_execute { yield }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cloudtasker/redis_client'
|
4
|
+
|
5
|
+
require_relative 'lock_error'
|
6
|
+
require_relative 'config'
|
7
|
+
|
8
|
+
require_relative 'conflict_strategy/base_strategy'
|
9
|
+
require_relative 'conflict_strategy/raise'
|
10
|
+
require_relative 'conflict_strategy/reject'
|
11
|
+
require_relative 'conflict_strategy/reschedule'
|
12
|
+
|
13
|
+
require_relative 'lock/base_lock'
|
14
|
+
require_relative 'lock/no_op'
|
15
|
+
require_relative 'lock/until_executed'
|
16
|
+
require_relative 'lock/until_executing'
|
17
|
+
require_relative 'lock/while_executing'
|
18
|
+
|
19
|
+
require_relative 'job'
|
20
|
+
|
21
|
+
require_relative 'middleware/client'
|
22
|
+
require_relative 'middleware/server'
|
23
|
+
|
24
|
+
module Cloudtasker
|
25
|
+
module UniqueJob
|
26
|
+
# Registration module
|
27
|
+
module Middleware
|
28
|
+
def self.configure
|
29
|
+
Cloudtasker.configure do |config|
|
30
|
+
config.client_middleware { |c| c.add(Middleware::Client) }
|
31
|
+
config.server_middleware { |c| c.add(Middleware::Server) }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Cloudtasker
|
4
|
+
module UniqueJob
|
5
|
+
module Middleware
|
6
|
+
# Client middleware, invoked when jobs are scheduled
|
7
|
+
class Client
|
8
|
+
def call(worker)
|
9
|
+
Job.new(worker).lock_instance.schedule { yield }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Cloudtasker
|
4
|
+
module UniqueJob
|
5
|
+
module Middleware
|
6
|
+
# Server middleware, invoked when jobs are executed
|
7
|
+
class Server
|
8
|
+
def call(worker)
|
9
|
+
Job.new(worker).lock_instance.execute { yield }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,211 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Cloudtasker
|
4
|
+
# Cloud Task based workers
|
5
|
+
module Worker
|
6
|
+
# Add class method to including class
|
7
|
+
def self.included(base)
|
8
|
+
base.extend(ClassMethods)
|
9
|
+
base.attr_accessor :job_args, :job_id, :job_meta, :job_reenqueued
|
10
|
+
end
|
11
|
+
|
12
|
+
#
|
13
|
+
# Return a worker instance from a serialized worker.
|
14
|
+
# A worker can be serialized by calling `MyWorker#to_json`
|
15
|
+
#
|
16
|
+
# @param [String] json Worker serialized as json.
|
17
|
+
#
|
18
|
+
# @return [Cloudtasker::Worker, nil] The instantiated worker.
|
19
|
+
#
|
20
|
+
def self.from_json(json)
|
21
|
+
from_hash(JSON.parse(json))
|
22
|
+
rescue JSON::ParserError
|
23
|
+
nil
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# Return a worker instance from a worker hash description.
|
28
|
+
# A worker hash description is typically generated by calling `MyWorker#to_h`
|
29
|
+
#
|
30
|
+
# @param [Hash] hash A worker hash description.
|
31
|
+
#
|
32
|
+
# @return [Cloudtasker::Worker, nil] The instantiated worker.
|
33
|
+
#
|
34
|
+
def self.from_hash(hash)
|
35
|
+
# Symbolize payload keys
|
36
|
+
payload = JSON.parse(hash.to_json, symbolize_names: true)
|
37
|
+
|
38
|
+
# Extract worker parameters
|
39
|
+
klass_name = payload&.dig(:worker)
|
40
|
+
return nil unless klass_name
|
41
|
+
|
42
|
+
# Check that worker class is a valid worker
|
43
|
+
worker_klass = Object.const_get(klass_name)
|
44
|
+
return nil unless worker_klass.include?(self)
|
45
|
+
|
46
|
+
# Return instantiated worker
|
47
|
+
worker_klass.new(payload.slice(:job_args, :job_id, :job_meta))
|
48
|
+
rescue NameError
|
49
|
+
nil
|
50
|
+
end
|
51
|
+
|
52
|
+
# Module class methods
|
53
|
+
module ClassMethods
|
54
|
+
#
|
55
|
+
# Set the worker runtime options.
|
56
|
+
#
|
57
|
+
# @param [Hash] opts The worker options
|
58
|
+
#
|
59
|
+
# @return [<Type>] <description>
|
60
|
+
#
|
61
|
+
def cloudtasker_options(opts = {})
|
62
|
+
opt_list = opts&.map { |k, v| [k.to_s, v] } || [] # stringify
|
63
|
+
@cloudtasker_options_hash = Hash[opt_list]
|
64
|
+
end
|
65
|
+
|
66
|
+
#
|
67
|
+
# Return the worker runtime options.
|
68
|
+
#
|
69
|
+
# @return [Hash] The worker runtime options.
|
70
|
+
#
|
71
|
+
def cloudtasker_options_hash
|
72
|
+
@cloudtasker_options_hash
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
# Enqueue worker in the backgroundf.
|
77
|
+
#
|
78
|
+
# @param [Array<any>] *args List of worker arguments
|
79
|
+
#
|
80
|
+
# @return [Google::Cloud::Tasks::V2beta3::Task] The Google Task response
|
81
|
+
#
|
82
|
+
def perform_async(*args)
|
83
|
+
perform_in(nil, *args)
|
84
|
+
end
|
85
|
+
|
86
|
+
#
|
87
|
+
# Enqueue worker and delay processing.
|
88
|
+
#
|
89
|
+
# @param [Integer, nil] interval The delay in seconds.
|
90
|
+
# @param [Array<any>] *args List of worker arguments.
|
91
|
+
#
|
92
|
+
# @return [Google::Cloud::Tasks::V2beta3::Task] The Google Task response
|
93
|
+
#
|
94
|
+
def perform_in(interval, *args)
|
95
|
+
new(job_args: args).schedule(interval: interval)
|
96
|
+
end
|
97
|
+
|
98
|
+
#
|
99
|
+
# Enqueue worker and delay processing.
|
100
|
+
#
|
101
|
+
# @param [Time, Integer] time_at The time at which the job should run.
|
102
|
+
# @param [Array<any>] *args List of worker arguments
|
103
|
+
#
|
104
|
+
# @return [Google::Cloud::Tasks::V2beta3::Task] The Google Task response
|
105
|
+
#
|
106
|
+
def perform_at(time_at, *args)
|
107
|
+
new(job_args: args).schedule(time_at: time_at)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
#
|
112
|
+
# Build a new worker instance.
|
113
|
+
#
|
114
|
+
# @param [Array<any>] job_args The list of perform args.
|
115
|
+
# @param [String] job_id A unique ID identifying this job.
|
116
|
+
#
|
117
|
+
def initialize(job_args: [], job_id: nil, job_meta: {})
|
118
|
+
@job_args = job_args
|
119
|
+
@job_id = job_id || SecureRandom.uuid
|
120
|
+
@job_meta = MetaStore.new(job_meta)
|
121
|
+
end
|
122
|
+
|
123
|
+
#
|
124
|
+
# Execute the worker by calling the `perform` with the args.
|
125
|
+
#
|
126
|
+
# @return [Any] The result of the perform.
|
127
|
+
#
|
128
|
+
def execute
|
129
|
+
Cloudtasker.config.server_middleware.invoke(self) do
|
130
|
+
perform(*job_args)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
#
|
135
|
+
# Enqueue a worker, with or without delay.
|
136
|
+
#
|
137
|
+
# @param [Integer] interval The delay in seconds.
|
138
|
+
#
|
139
|
+
# @param [Time, Integer] interval The time at which the job should run
|
140
|
+
#
|
141
|
+
# @return [Google::Cloud::Tasks::V2beta3::Task] The Google Task response
|
142
|
+
#
|
143
|
+
def schedule(interval: nil, time_at: nil)
|
144
|
+
Cloudtasker.config.client_middleware.invoke(self) do
|
145
|
+
Task.new(self).schedule(interval: interval, time_at: time_at)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
#
|
150
|
+
# Helper method used to re-enqueue the job. Re-enqueued
|
151
|
+
# jobs keep the same job_id.
|
152
|
+
#
|
153
|
+
# This helper may be useful when jobs must pause activity due to external
|
154
|
+
# factors such as when a third-party API is throttling the rate of API calls.
|
155
|
+
#
|
156
|
+
# @param [Integer] interval Delay to wait before processing the job again (in seconds).
|
157
|
+
#
|
158
|
+
# @return [Google::Cloud::Tasks::V2beta3::Task] The Google Task response
|
159
|
+
#
|
160
|
+
def reenqueue(interval)
|
161
|
+
@job_reenqueued = true
|
162
|
+
schedule(interval: interval)
|
163
|
+
end
|
164
|
+
|
165
|
+
#
|
166
|
+
# Return a new instance of the worker with the same args and metadata
|
167
|
+
# but with a different id.
|
168
|
+
#
|
169
|
+
# @return [<Type>] <description>
|
170
|
+
#
|
171
|
+
def new_instance
|
172
|
+
self.class.new(job_args: job_args, job_meta: job_meta)
|
173
|
+
end
|
174
|
+
|
175
|
+
#
|
176
|
+
# Return a hash description of the worker.
|
177
|
+
#
|
178
|
+
# @return [Hash] The worker hash description.
|
179
|
+
#
|
180
|
+
def to_h
|
181
|
+
{
|
182
|
+
worker: self.class.to_s,
|
183
|
+
job_id: job_id,
|
184
|
+
job_args: job_args,
|
185
|
+
job_meta: job_meta.to_h
|
186
|
+
}
|
187
|
+
end
|
188
|
+
|
189
|
+
#
|
190
|
+
# Return a json representation of the worker.
|
191
|
+
#
|
192
|
+
# @param [Array<any>] *args Arguments passed to to_json.
|
193
|
+
#
|
194
|
+
# @return [String] The worker json representation.
|
195
|
+
#
|
196
|
+
def to_json(*args)
|
197
|
+
to_h.to_json(*args)
|
198
|
+
end
|
199
|
+
|
200
|
+
#
|
201
|
+
# Equality operator.
|
202
|
+
#
|
203
|
+
# @param [Any] other The object to compare.
|
204
|
+
#
|
205
|
+
# @return [Boolean] True if the object is equal.
|
206
|
+
#
|
207
|
+
def ==(other)
|
208
|
+
other.is_a?(self.class) && other.job_id == job_id
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
metadata
ADDED
@@ -0,0 +1,286 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: cloudtasker
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Arnaud Lachaume
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-11-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: fugit
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: google-cloud-tasks
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: jwt
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: redis
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bundler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '2.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '2.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '10.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '10.0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '3.0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '3.0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rubocop
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - '='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.76.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.76.0
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: rubocop-rspec
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: timecop
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: rails
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: rspec-rails
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: sqlite3
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - ">="
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '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'
|
195
|
+
description: Manage GCP Cloud Tasks in your app.
|
196
|
+
email:
|
197
|
+
- arnaud.lachaume@keypup.io
|
198
|
+
executables: []
|
199
|
+
extensions: []
|
200
|
+
extra_rdoc_files: []
|
201
|
+
files:
|
202
|
+
- ".gitignore"
|
203
|
+
- ".rspec"
|
204
|
+
- ".rubocop.yml"
|
205
|
+
- ".travis.yml"
|
206
|
+
- CODE_OF_CONDUCT.md
|
207
|
+
- Gemfile
|
208
|
+
- Gemfile.lock
|
209
|
+
- LICENSE.txt
|
210
|
+
- README.md
|
211
|
+
- Rakefile
|
212
|
+
- app/controllers/cloudtasker/application_controller.rb
|
213
|
+
- app/controllers/cloudtasker/worker_controller.rb
|
214
|
+
- bin/console
|
215
|
+
- bin/setup
|
216
|
+
- cloudtasker.gemspec
|
217
|
+
- config/routes.rb
|
218
|
+
- lib/cloudtasker.rb
|
219
|
+
- lib/cloudtasker/authentication_error.rb
|
220
|
+
- lib/cloudtasker/authenticator.rb
|
221
|
+
- lib/cloudtasker/batch.rb
|
222
|
+
- lib/cloudtasker/batch/batch_progress.rb
|
223
|
+
- lib/cloudtasker/batch/config.rb
|
224
|
+
- lib/cloudtasker/batch/extension/worker.rb
|
225
|
+
- lib/cloudtasker/batch/job.rb
|
226
|
+
- lib/cloudtasker/batch/middleware.rb
|
227
|
+
- lib/cloudtasker/batch/middleware/server.rb
|
228
|
+
- lib/cloudtasker/config.rb
|
229
|
+
- lib/cloudtasker/cron.rb
|
230
|
+
- lib/cloudtasker/cron/config.rb
|
231
|
+
- lib/cloudtasker/cron/job.rb
|
232
|
+
- lib/cloudtasker/cron/middleware.rb
|
233
|
+
- lib/cloudtasker/cron/middleware/server.rb
|
234
|
+
- lib/cloudtasker/cron/schedule.rb
|
235
|
+
- lib/cloudtasker/engine.rb
|
236
|
+
- lib/cloudtasker/invalid_worker_error.rb
|
237
|
+
- lib/cloudtasker/meta_store.rb
|
238
|
+
- lib/cloudtasker/middleware/chain.rb
|
239
|
+
- lib/cloudtasker/redis_client.rb
|
240
|
+
- lib/cloudtasker/task.rb
|
241
|
+
- lib/cloudtasker/unique_job.rb
|
242
|
+
- lib/cloudtasker/unique_job/config.rb
|
243
|
+
- lib/cloudtasker/unique_job/conflict_strategy/base_strategy.rb
|
244
|
+
- lib/cloudtasker/unique_job/conflict_strategy/raise.rb
|
245
|
+
- lib/cloudtasker/unique_job/conflict_strategy/reject.rb
|
246
|
+
- lib/cloudtasker/unique_job/conflict_strategy/reschedule.rb
|
247
|
+
- lib/cloudtasker/unique_job/job.rb
|
248
|
+
- lib/cloudtasker/unique_job/lock/base_lock.rb
|
249
|
+
- lib/cloudtasker/unique_job/lock/no_op.rb
|
250
|
+
- lib/cloudtasker/unique_job/lock/until_executed.rb
|
251
|
+
- lib/cloudtasker/unique_job/lock/until_executing.rb
|
252
|
+
- lib/cloudtasker/unique_job/lock/while_executing.rb
|
253
|
+
- lib/cloudtasker/unique_job/lock_error.rb
|
254
|
+
- lib/cloudtasker/unique_job/middleware.rb
|
255
|
+
- lib/cloudtasker/unique_job/middleware/client.rb
|
256
|
+
- lib/cloudtasker/unique_job/middleware/server.rb
|
257
|
+
- lib/cloudtasker/version.rb
|
258
|
+
- lib/cloudtasker/worker.rb
|
259
|
+
homepage: https://github.com/keypup-io/cloudtasker
|
260
|
+
licenses:
|
261
|
+
- MIT
|
262
|
+
metadata:
|
263
|
+
homepage_uri: https://github.com/keypup-io/cloudtasker
|
264
|
+
source_code_uri: https://github.com/keypup-io/cloudtasker
|
265
|
+
changelog_uri: https://github.com/keypup-io/cloudtasker/master/tree/CHANGELOG.md
|
266
|
+
post_install_message:
|
267
|
+
rdoc_options: []
|
268
|
+
require_paths:
|
269
|
+
- lib
|
270
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
271
|
+
requirements:
|
272
|
+
- - ">="
|
273
|
+
- !ruby/object:Gem::Version
|
274
|
+
version: '0'
|
275
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
276
|
+
requirements:
|
277
|
+
- - ">="
|
278
|
+
- !ruby/object:Gem::Version
|
279
|
+
version: '0'
|
280
|
+
requirements: []
|
281
|
+
rubyforge_project:
|
282
|
+
rubygems_version: 2.7.9
|
283
|
+
signing_key:
|
284
|
+
specification_version: 4
|
285
|
+
summary: Manage GCP Cloud Tasks in your app.
|
286
|
+
test_files: []
|