cloudtasker 0.14.rc1 → 0.15.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 +19 -18
- data/.gitignore +1 -1
- data/.rubocop.yml +12 -12
- data/Appraisals +19 -16
- data/CHANGELOG.md +12 -3
- data/Gemfile +1 -1
- data/README.md +6 -8
- data/app/controllers/cloudtasker/worker_controller.rb +1 -1
- data/cloudtasker.gemspec +1 -1
- data/docs/STORABLE_JOBS.md +1 -1
- data/docs/UNIQUE_JOBS.md +1 -0
- data/gemfiles/google_cloud_tasks_1.0.gemfile +1 -1
- data/gemfiles/google_cloud_tasks_1.1.gemfile +1 -1
- data/gemfiles/google_cloud_tasks_1.2.gemfile +1 -1
- data/gemfiles/google_cloud_tasks_1.3.gemfile +1 -1
- data/gemfiles/google_cloud_tasks_1.4.gemfile +1 -1
- data/gemfiles/google_cloud_tasks_1.5.gemfile +1 -1
- data/gemfiles/google_cloud_tasks_2.0.gemfile +1 -1
- data/gemfiles/google_cloud_tasks_2.1.gemfile +1 -1
- data/gemfiles/rails_6.1.gemfile +3 -1
- data/gemfiles/rails_7.0.gemfile +1 -1
- data/gemfiles/{rails_5.2.gemfile → rails_7.1.gemfile} +2 -2
- data/gemfiles/{rails_6.0.gemfile → rails_8.0.gemfile} +2 -2
- data/gemfiles/rails_8.1.gemfile +18 -0
- data/gemfiles/semantic_logger_3.4.gemfile +1 -1
- data/gemfiles/semantic_logger_4.6.gemfile +1 -1
- data/gemfiles/semantic_logger_4.7.0.gemfile +1 -1
- data/gemfiles/semantic_logger_4.7.2.gemfile +1 -1
- data/lib/cloudtasker/backend/redis_task.rb +1 -1
- data/lib/cloudtasker/config.rb +3 -0
- data/lib/cloudtasker/redis_client.rb +17 -37
- data/lib/cloudtasker/unique_job/lock/until_completed.rb +40 -0
- data/lib/cloudtasker/unique_job/middleware.rb +1 -0
- data/lib/cloudtasker/version.rb +1 -1
- data/lib/cloudtasker/worker_logger.rb +2 -2
- metadata +8 -7
- data/.github/workflows/test_ruby_2.7.yml +0 -38
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 3acbfbd2b8d2ac1c4260b01fc44c4bd43c0061db35eeb84a0bc5f4c1a9358204
|
|
4
|
+
data.tar.gz: 1a9e2d8048b39eac16dc794671796025a16c1f27e95967adde23ad4361be3610
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 915fb26b5107680819a63cd55d2097f56675779f160eb284e109aacbbd111af358e71e5afc99194ec1846e022a73797f57d5e7b8be7b3b2684cc3b30f0fdc787
|
|
7
|
+
data.tar.gz: 3ca5533216e37a51b2393720d60a6a969ca9c887c0151391f9409921bc952062fd6a82855e9c21b0673a35a604ba40fa56f9f72a590e8481397388c70306ff27
|
|
@@ -8,25 +8,26 @@ jobs:
|
|
|
8
8
|
strategy:
|
|
9
9
|
matrix:
|
|
10
10
|
ruby:
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
11
|
+
- "3.0"
|
|
12
|
+
- "3.1"
|
|
13
|
+
- "3.2"
|
|
14
|
+
- "3.3"
|
|
15
|
+
- "3.4"
|
|
15
16
|
appraisal:
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
-
|
|
29
|
-
-
|
|
17
|
+
- "google_cloud_tasks_1.0"
|
|
18
|
+
- "google_cloud_tasks_1.1"
|
|
19
|
+
- "google_cloud_tasks_1.2"
|
|
20
|
+
- "google_cloud_tasks_1.3"
|
|
21
|
+
- "google_cloud_tasks_1.4"
|
|
22
|
+
- "google_cloud_tasks_1.5"
|
|
23
|
+
- "google_cloud_tasks_2.0"
|
|
24
|
+
- "google_cloud_tasks_2.1"
|
|
25
|
+
- "rails_6.1"
|
|
26
|
+
- "rails_7.0"
|
|
27
|
+
- "semantic_logger_3.4"
|
|
28
|
+
- "semantic_logger_4.6"
|
|
29
|
+
- "semantic_logger_4.7.0"
|
|
30
|
+
- "semantic_logger_4.7.2"
|
|
30
31
|
env:
|
|
31
32
|
BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.appraisal }}.gemfile
|
|
32
33
|
steps:
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
|
@@ -3,10 +3,10 @@ require: rubocop-rspec
|
|
|
3
3
|
AllCops:
|
|
4
4
|
NewCops: enable
|
|
5
5
|
SuggestExtensions: false
|
|
6
|
-
TargetRubyVersion:
|
|
6
|
+
TargetRubyVersion: 3.0
|
|
7
7
|
Exclude:
|
|
8
|
-
-
|
|
9
|
-
-
|
|
8
|
+
- "gemfiles/**/*"
|
|
9
|
+
- "vendor/**/*"
|
|
10
10
|
|
|
11
11
|
Metrics/ClassLength:
|
|
12
12
|
Max: 300
|
|
@@ -17,7 +17,7 @@ Metrics/ModuleLength:
|
|
|
17
17
|
Metrics/AbcSize:
|
|
18
18
|
Max: 30
|
|
19
19
|
Exclude:
|
|
20
|
-
-
|
|
20
|
+
- "spec/support/*"
|
|
21
21
|
|
|
22
22
|
Metrics/PerceivedComplexity:
|
|
23
23
|
Max: 20
|
|
@@ -30,7 +30,7 @@ Metrics/MethodLength:
|
|
|
30
30
|
|
|
31
31
|
RSpec/DescribeClass:
|
|
32
32
|
Exclude:
|
|
33
|
-
-
|
|
33
|
+
- "spec/integration/**/*_spec.rb"
|
|
34
34
|
|
|
35
35
|
RSpec/ExpectInHook:
|
|
36
36
|
Enabled: false
|
|
@@ -44,12 +44,12 @@ RSpec/ScatteredSetup:
|
|
|
44
44
|
Metrics/BlockLength:
|
|
45
45
|
Exclude:
|
|
46
46
|
- cloudtasker.gemspec
|
|
47
|
-
-
|
|
47
|
+
- "spec/**/*"
|
|
48
48
|
|
|
49
49
|
Style/Documentation:
|
|
50
50
|
Exclude:
|
|
51
|
-
-
|
|
52
|
-
-
|
|
51
|
+
- "examples/**/*"
|
|
52
|
+
- "spec/**/*"
|
|
53
53
|
|
|
54
54
|
Metrics/ParameterLists:
|
|
55
55
|
CountKeywordArgs: false
|
|
@@ -59,15 +59,15 @@ Metrics/CyclomaticComplexity:
|
|
|
59
59
|
|
|
60
60
|
Lint/EmptyBlock:
|
|
61
61
|
Exclude:
|
|
62
|
-
-
|
|
62
|
+
- "examples/rails/config/routes.rb"
|
|
63
63
|
|
|
64
64
|
RSpec/MessageSpies:
|
|
65
65
|
Enabled: false
|
|
66
66
|
|
|
67
67
|
RSpec/MultipleExpectations:
|
|
68
68
|
Exclude:
|
|
69
|
-
-
|
|
70
|
-
-
|
|
69
|
+
- "examples/**/*"
|
|
70
|
+
- "spec/integration/**/*"
|
|
71
71
|
|
|
72
72
|
RSpec/AnyInstance:
|
|
73
73
|
Enabled: false
|
|
@@ -90,4 +90,4 @@ RSpec/VerifiedDoubles:
|
|
|
90
90
|
Exclude:
|
|
91
91
|
- spec/cloudtasker/cloud_task_spec.rb
|
|
92
92
|
- spec/cloudtasker/backend/google_cloud_task_v1_spec.rb
|
|
93
|
-
- spec/cloudtasker/backend/google_cloud_task_v2_spec.rb
|
|
93
|
+
- spec/cloudtasker/backend/google_cloud_task_v2_spec.rb
|
data/Appraisals
CHANGED
|
@@ -32,28 +32,31 @@ appraise 'google_cloud_tasks_2.1' do
|
|
|
32
32
|
gem 'google-cloud-tasks', '~> 2.1.0'
|
|
33
33
|
end
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
appraise 'rails_6.1' do
|
|
36
|
+
gem 'rails', '~> 6.1.0'
|
|
37
|
+
gem 'rspec-rails'
|
|
38
|
+
gem 'mutex_m'
|
|
39
|
+
gem 'drb'
|
|
40
|
+
end
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
end
|
|
42
|
+
appraise 'rails_7.0' do
|
|
43
|
+
gem 'rails', '~> 7.0.0'
|
|
44
|
+
gem 'rspec-rails'
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
appraise '
|
|
48
|
-
gem 'rails', '~>
|
|
47
|
+
appraise 'rails_7.1' do
|
|
48
|
+
gem 'rails', '~> 7.1'
|
|
49
49
|
gem 'rspec-rails'
|
|
50
50
|
end
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
appraise 'rails_8.0' do
|
|
53
|
+
gem 'rails', '~> 8.0'
|
|
54
|
+
gem 'rspec-rails'
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
appraise 'rails_8.1' do
|
|
58
|
+
gem 'rails', '~> 8.1'
|
|
59
|
+
gem 'rspec-rails'
|
|
57
60
|
end
|
|
58
61
|
|
|
59
62
|
appraise 'semantic_logger_3.4' do
|
data/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## [v0.
|
|
3
|
+
## [v0.15.rc1](https://github.com/keypup-io/cloudtasker/tree/v0.15.rc1) (2025-10-30)
|
|
4
4
|
|
|
5
|
-
[Full Changelog](https://github.com/keypup-io/cloudtasker/compare/v0.
|
|
5
|
+
[Full Changelog](https://github.com/keypup-io/cloudtasker/compare/v0.14.0...v0.15.rc1)
|
|
6
|
+
|
|
7
|
+
**Improvements:**
|
|
8
|
+
- Unique Jobs: add `until_completed` strategy to lock jobs until they are completed or have exhausted all retries (thanks @jam-packed).
|
|
9
|
+
|
|
10
|
+
**Maintenance:**
|
|
11
|
+
- Supported rubies: drop support for ruby `2.7`. Cloudtasker now requires ruby `3.0` and above.
|
|
12
|
+
|
|
13
|
+
## [v0.14.0](https://github.com/keypup-io/cloudtasker/tree/v0.14.0) (2025-02-11)
|
|
14
|
+
|
|
15
|
+
[Full Changelog](https://github.com/keypup-io/cloudtasker/compare/v0.13.2...v0.14.0)
|
|
6
16
|
|
|
7
17
|
**Improvements:**
|
|
8
18
|
- Authentication: To support OIDC and regular Cloudtasker authentication, we moved the Cloudtasker Authentication header from `Authorization` to `X-Cloudtasker-Authorization`. Backward compatibility is maintained for existing jobs.
|
|
@@ -23,7 +33,6 @@
|
|
|
23
33
|
- Rails: Use `skip_forgery_protection` instead of `skip_before_action`. The later was causing occasional issues on some setups.
|
|
24
34
|
|
|
25
35
|
|
|
26
|
-
|
|
27
36
|
## [v0.13.2](https://github.com/keypup-io/cloudtasker/tree/v0.13.2) (2023-07-02)
|
|
28
37
|
|
|
29
38
|
[Full Changelog](https://github.com/keypup-io/cloudtasker/compare/v0.13.1...v0.13.2)
|
data/Gemfile
CHANGED
data/README.md
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
 is out and it's quite big ([Changelog](https://github.com/keypup-io/cloudtasker/blob/master/CHANGELOG.md)). Any help testing this release is welcome, and feel free to open issues if you spot any regression.
|
|
1
|
+
 [](https://badge.fury.io/rb/cloudtasker)
|
|
4
2
|
|
|
5
3
|
# Cloudtasker
|
|
6
4
|
|
|
@@ -428,7 +426,7 @@ Cloudtasker.configure do |config|
|
|
|
428
426
|
# See https://cloud.google.com/tasks/docs/creating-http-target-tasks#sa for more information on
|
|
429
427
|
# setting up service accounts for use with Cloud Tasks.
|
|
430
428
|
#
|
|
431
|
-
# Supported since: v0.14.
|
|
429
|
+
# Supported since: v0.14.0
|
|
432
430
|
#
|
|
433
431
|
# Default: nil
|
|
434
432
|
#
|
|
@@ -698,7 +696,7 @@ end
|
|
|
698
696
|
See the [Cloudtasker::Worker class](lib/cloudtasker/worker.rb) for more information on attributes available to be logged in your `log_context_processor` proc.
|
|
699
697
|
|
|
700
698
|
### Truncating log arguments
|
|
701
|
-
**Supported since**: `v0.14.
|
|
699
|
+
**Supported since**: `v0.14.0`
|
|
702
700
|
|
|
703
701
|
By default Cloudtasker does not log job arguments as arguments can contain sensitive data and generate voluminous logs, which may lead to noticeable costs with your log provider (e.g. GCP Logging). Also some providers (e.g. GCP Logging) will automatically truncate log entries that are too big and reduce their searchability.
|
|
704
702
|
|
|
@@ -834,7 +832,7 @@ By default jobs are retried 25 times - using an exponential backoff - before bei
|
|
|
834
832
|
|
|
835
833
|
Note that the number of retries set on your Cloud Task queue should be many times higher than the number of retries configured in Cloudtasker because Cloud Task also includes failures to connect to your application. Ideally set the number of retries to `unlimited` in Cloud Tasks.
|
|
836
834
|
|
|
837
|
-
**Note**: Versions prior to `v0.14.
|
|
835
|
+
**Note**: Versions prior to `v0.14.0` use the `X-CloudTasks-TaskRetryCount` header for retries instead of the `X-CloudTasks-TaskExecutionCount` header to detect the number of retries, because there a previous bug on the GCP side which made the `X-CloudTasks-TaskExecutionCount` stay at zero instead of increasing on successive executions. Versions prior to `v0.14.0` count any failure as failure, including failures due to the backend being unavailable (`HTTP 503`). Versions `v0.14.0` and later only count application failure (`HTTP 4xx`) as failure for retry purpose.
|
|
838
836
|
|
|
839
837
|
E.g. Set max number of retries globally via the cloudtasker initializer.
|
|
840
838
|
```ruby
|
|
@@ -891,7 +889,7 @@ end
|
|
|
891
889
|
```
|
|
892
890
|
|
|
893
891
|
### Conditional reenqueues using retry errors
|
|
894
|
-
**Supported since**: `v0.14.
|
|
892
|
+
**Supported since**: `v0.14.0`
|
|
895
893
|
|
|
896
894
|
If your worker is waiting for some precondition to occur and you want to re-enqueue it until the condition has been met, you can raise a `Cloudtasker::RetryWorkerError`. This special error will fail your job **without logging an error** while still increasing the number of retries.
|
|
897
895
|
|
|
@@ -1005,7 +1003,7 @@ Each testing mode accepts a block argument to temporarily switch to it:
|
|
|
1005
1003
|
Cloudtasker::Testing.fake!
|
|
1006
1004
|
|
|
1007
1005
|
# Enable inline! mode temporarily for a given test
|
|
1008
|
-
Cloudtasker.inline! do
|
|
1006
|
+
Cloudtasker::Testing.inline! do
|
|
1009
1007
|
MyWorker.perform_async(1,2)
|
|
1010
1008
|
end
|
|
1011
1009
|
```
|
|
@@ -94,7 +94,7 @@ module Cloudtasker
|
|
|
94
94
|
# Verify content signature
|
|
95
95
|
Authenticator.verify_signature!(signature, json_payload)
|
|
96
96
|
else
|
|
97
|
-
# Get authorization token from custom header (since v0.14.
|
|
97
|
+
# Get authorization token from custom header (since v0.14.0) or fallback to
|
|
98
98
|
# former authorization header (jobs enqueued by v0.13 and below)
|
|
99
99
|
bearer_token = request.headers[Cloudtasker::Config::CT_AUTHORIZATION_HEADER].to_s.split.last ||
|
|
100
100
|
request.headers[Cloudtasker::Config::OIDC_AUTHORIZATION_HEADER].to_s.split.last
|
data/cloudtasker.gemspec
CHANGED
|
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
|
|
|
28
28
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
29
29
|
spec.require_paths = ['lib']
|
|
30
30
|
|
|
31
|
-
spec.required_ruby_version = '>=
|
|
31
|
+
spec.required_ruby_version = '>= 3.0'
|
|
32
32
|
|
|
33
33
|
spec.add_dependency 'activesupport'
|
|
34
34
|
spec.add_dependency 'connection_pool'
|
data/docs/STORABLE_JOBS.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Cloudtasker Storable Jobs
|
|
2
2
|
|
|
3
|
-
**Supported since**: `v0.14.
|
|
3
|
+
**Supported since**: `v0.14.0`
|
|
4
4
|
**Note**: this extension requires redis
|
|
5
5
|
|
|
6
6
|
The Cloudtasker storage extension allows you to park jobs in a specific garage lane and enqueue (pull) them when specific conditions have been met.
|
data/docs/UNIQUE_JOBS.md
CHANGED
|
@@ -70,6 +70,7 @@ For each lock strategy the table specifies the lock period (start/end) and which
|
|
|
70
70
|
| `until_executing` | The job is scheduled | The job starts processing | `reject` (default) or `raise` |
|
|
71
71
|
| `while_executing` | The job starts processing | The job ends processing | `reject` (default), `reschedule` or `raise` |
|
|
72
72
|
| `until_executed` | The job is scheduled | The job ends processing | `reject` (default) or `raise` |
|
|
73
|
+
| `until_completed` | The job is scheduled | The job completes successfully or a `DeadWorkerError` is raised. Supported since `v0.15.rc1`. | `reject` (default) or `raise` |
|
|
73
74
|
|
|
74
75
|
## Available conflict strategies
|
|
75
76
|
|
data/gemfiles/rails_6.1.gemfile
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
source "https://rubygems.org"
|
|
4
4
|
|
|
5
|
-
gem "appraisal"
|
|
5
|
+
gem "appraisal"
|
|
6
6
|
gem "bundler", "~> 2.0"
|
|
7
7
|
gem "rake", ">= 12.3.3"
|
|
8
8
|
gem "rspec", "~> 3.0"
|
|
@@ -14,5 +14,7 @@ gem "timecop"
|
|
|
14
14
|
gem "webmock"
|
|
15
15
|
gem "rails", "~> 6.1.0"
|
|
16
16
|
gem "rspec-rails"
|
|
17
|
+
gem "mutex_m"
|
|
18
|
+
gem "drb"
|
|
17
19
|
|
|
18
20
|
gemspec path: "../"
|
data/gemfiles/rails_7.0.gemfile
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
source "https://rubygems.org"
|
|
4
4
|
|
|
5
|
-
gem "appraisal"
|
|
5
|
+
gem "appraisal"
|
|
6
6
|
gem "bundler", "~> 2.0"
|
|
7
7
|
gem "rake", ">= 12.3.3"
|
|
8
8
|
gem "rspec", "~> 3.0"
|
|
@@ -12,7 +12,7 @@ gem "rubocop-rspec", "~> 3.0.1"
|
|
|
12
12
|
gem "semantic_logger"
|
|
13
13
|
gem "timecop"
|
|
14
14
|
gem "webmock"
|
|
15
|
-
gem "rails", "~>
|
|
15
|
+
gem "rails", "~> 7.1"
|
|
16
16
|
gem "rspec-rails"
|
|
17
17
|
|
|
18
18
|
gemspec path: "../"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
source "https://rubygems.org"
|
|
4
4
|
|
|
5
|
-
gem "appraisal"
|
|
5
|
+
gem "appraisal"
|
|
6
6
|
gem "bundler", "~> 2.0"
|
|
7
7
|
gem "rake", ">= 12.3.3"
|
|
8
8
|
gem "rspec", "~> 3.0"
|
|
@@ -12,7 +12,7 @@ gem "rubocop-rspec", "~> 3.0.1"
|
|
|
12
12
|
gem "semantic_logger"
|
|
13
13
|
gem "timecop"
|
|
14
14
|
gem "webmock"
|
|
15
|
-
gem "rails", "~>
|
|
15
|
+
gem "rails", "~> 8.0"
|
|
16
16
|
gem "rspec-rails"
|
|
17
17
|
|
|
18
18
|
gemspec path: "../"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# This file was generated by Appraisal
|
|
2
|
+
|
|
3
|
+
source "https://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gem "appraisal"
|
|
6
|
+
gem "bundler", "~> 2.0"
|
|
7
|
+
gem "rake", ">= 12.3.3"
|
|
8
|
+
gem "rspec", "~> 3.0"
|
|
9
|
+
gem "rspec-json_expectations", "~> 2.2"
|
|
10
|
+
gem "rubocop", "~> 1.64.1"
|
|
11
|
+
gem "rubocop-rspec", "~> 3.0.1"
|
|
12
|
+
gem "semantic_logger"
|
|
13
|
+
gem "timecop"
|
|
14
|
+
gem "webmock"
|
|
15
|
+
gem "rails", "~> 8.1"
|
|
16
|
+
gem "rspec-rails"
|
|
17
|
+
|
|
18
|
+
gemspec path: "../"
|
data/lib/cloudtasker/config.rb
CHANGED
|
@@ -71,6 +71,9 @@ module Cloudtasker
|
|
|
71
71
|
# failures due to the instance being unreachable.
|
|
72
72
|
DEFAULT_MAX_RETRY_ATTEMPTS = 25
|
|
73
73
|
|
|
74
|
+
# How long to wait between retries in local server mode
|
|
75
|
+
LOCAL_SERVER_RETRY_DELAY = (ENV['CLOUDTASKER_LOCAL_RETRY_DELAY'] || 20).to_i # seconds
|
|
76
|
+
|
|
74
77
|
PROCESSOR_HOST_MISSING = <<~DOC
|
|
75
78
|
Missing host for processing.
|
|
76
79
|
Please specify a processor hostname in form of `https://some-public-dns.example.com`'
|
|
@@ -132,45 +132,25 @@ module Cloudtasker
|
|
|
132
132
|
list
|
|
133
133
|
end
|
|
134
134
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
super
|
|
152
|
-
end
|
|
153
|
-
end
|
|
154
|
-
else
|
|
155
|
-
#
|
|
156
|
-
# Delegate all methods to the redis client.
|
|
157
|
-
# Ruby 3 delegation method style.
|
|
158
|
-
#
|
|
159
|
-
# @param [String, Symbol] name The method to delegate.
|
|
160
|
-
# @param [Array<any>] *args The list of method positional arguments.
|
|
161
|
-
# @param [Hash<any>] *kwargs The list of method keyword arguments.
|
|
162
|
-
# @param [Proc] &block Block passed to the method.
|
|
163
|
-
#
|
|
164
|
-
# @return [Any] The method return value
|
|
165
|
-
#
|
|
166
|
-
def method_missing(name, *args, **kwargs, &block)
|
|
167
|
-
if Redis.method_defined?(name)
|
|
168
|
-
client.with { |c| c.send(name, *args, **kwargs, &block) }
|
|
169
|
-
else
|
|
170
|
-
super
|
|
171
|
-
end
|
|
135
|
+
#
|
|
136
|
+
# Delegate all methods to the redis client.
|
|
137
|
+
# Ruby 3 delegation method style.
|
|
138
|
+
#
|
|
139
|
+
# @param [String, Symbol] name The method to delegate.
|
|
140
|
+
# @param [Array<any>] *args The list of method positional arguments.
|
|
141
|
+
# @param [Hash<any>] *kwargs The list of method keyword arguments.
|
|
142
|
+
# @param [Proc] &block Block passed to the method.
|
|
143
|
+
#
|
|
144
|
+
# @return [Any] The method return value
|
|
145
|
+
#
|
|
146
|
+
def method_missing(name, ...)
|
|
147
|
+
if Redis.method_defined?(name)
|
|
148
|
+
client.with { |c| c.send(name, ...) }
|
|
149
|
+
else
|
|
150
|
+
super
|
|
172
151
|
end
|
|
173
152
|
end
|
|
153
|
+
|
|
174
154
|
#
|
|
175
155
|
# Check if the class respond to a certain method.
|
|
176
156
|
#
|
|
@@ -0,0 +1,40 @@
|
|
|
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. Unlocks only on successful completion
|
|
8
|
+
# or when a DeadWorkerError is raised.
|
|
9
|
+
class UntilCompleted < BaseLock
|
|
10
|
+
#
|
|
11
|
+
# Acquire a lock for the job and trigger a conflict
|
|
12
|
+
# if the lock could not be acquired.
|
|
13
|
+
#
|
|
14
|
+
def schedule(&block)
|
|
15
|
+
job.lock!
|
|
16
|
+
yield
|
|
17
|
+
rescue LockError
|
|
18
|
+
conflict_instance.on_schedule(&block)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
#
|
|
22
|
+
# Acquire a lock for the job and trigger a conflict
|
|
23
|
+
# if the lock could not be acquired.
|
|
24
|
+
#
|
|
25
|
+
def execute(&block)
|
|
26
|
+
job.lock!
|
|
27
|
+
yield
|
|
28
|
+
# Unlock on successful completion
|
|
29
|
+
job.unlock!
|
|
30
|
+
rescue LockError
|
|
31
|
+
conflict_instance.on_execute(&block)
|
|
32
|
+
rescue Cloudtasker::DeadWorkerError
|
|
33
|
+
# Unlock when DeadWorkerError is raised
|
|
34
|
+
job.unlock!
|
|
35
|
+
raise
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
data/lib/cloudtasker/version.rb
CHANGED
|
@@ -184,9 +184,9 @@ module Cloudtasker
|
|
|
184
184
|
#
|
|
185
185
|
# @return [Any] The method return value
|
|
186
186
|
#
|
|
187
|
-
def method_missing(name,
|
|
187
|
+
def method_missing(name, ...)
|
|
188
188
|
if logger.respond_to?(name)
|
|
189
|
-
logger.send(name,
|
|
189
|
+
logger.send(name, ...)
|
|
190
190
|
else
|
|
191
191
|
super
|
|
192
192
|
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.15.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: 2025-10-30 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -117,7 +117,6 @@ extensions: []
|
|
|
117
117
|
extra_rdoc_files: []
|
|
118
118
|
files:
|
|
119
119
|
- ".github/workflows/lint_rubocop.yml"
|
|
120
|
-
- ".github/workflows/test_ruby_2.7.yml"
|
|
121
120
|
- ".github/workflows/test_ruby_3.x.yml"
|
|
122
121
|
- ".gitignore"
|
|
123
122
|
- ".rspec"
|
|
@@ -149,10 +148,11 @@ files:
|
|
|
149
148
|
- gemfiles/google_cloud_tasks_1.5.gemfile
|
|
150
149
|
- gemfiles/google_cloud_tasks_2.0.gemfile
|
|
151
150
|
- gemfiles/google_cloud_tasks_2.1.gemfile
|
|
152
|
-
- gemfiles/rails_5.2.gemfile
|
|
153
|
-
- gemfiles/rails_6.0.gemfile
|
|
154
151
|
- gemfiles/rails_6.1.gemfile
|
|
155
152
|
- gemfiles/rails_7.0.gemfile
|
|
153
|
+
- gemfiles/rails_7.1.gemfile
|
|
154
|
+
- gemfiles/rails_8.0.gemfile
|
|
155
|
+
- gemfiles/rails_8.1.gemfile
|
|
156
156
|
- gemfiles/semantic_logger_3.4.gemfile
|
|
157
157
|
- gemfiles/semantic_logger_4.6.gemfile
|
|
158
158
|
- gemfiles/semantic_logger_4.7.0.gemfile
|
|
@@ -200,6 +200,7 @@ files:
|
|
|
200
200
|
- lib/cloudtasker/unique_job/job.rb
|
|
201
201
|
- lib/cloudtasker/unique_job/lock/base_lock.rb
|
|
202
202
|
- lib/cloudtasker/unique_job/lock/no_op.rb
|
|
203
|
+
- lib/cloudtasker/unique_job/lock/until_completed.rb
|
|
203
204
|
- lib/cloudtasker/unique_job/lock/until_executed.rb
|
|
204
205
|
- lib/cloudtasker/unique_job/lock/until_executing.rb
|
|
205
206
|
- lib/cloudtasker/unique_job/lock/while_executing.rb
|
|
@@ -229,14 +230,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
229
230
|
requirements:
|
|
230
231
|
- - ">="
|
|
231
232
|
- !ruby/object:Gem::Version
|
|
232
|
-
version:
|
|
233
|
+
version: '3.0'
|
|
233
234
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
234
235
|
requirements:
|
|
235
236
|
- - ">="
|
|
236
237
|
- !ruby/object:Gem::Version
|
|
237
238
|
version: '0'
|
|
238
239
|
requirements: []
|
|
239
|
-
rubygems_version: 3.5.
|
|
240
|
+
rubygems_version: 3.5.22
|
|
240
241
|
signing_key:
|
|
241
242
|
specification_version: 4
|
|
242
243
|
summary: Background jobs for Ruby using Google Cloud Tasks (beta)
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
name: Ruby 2.7
|
|
2
|
-
|
|
3
|
-
on: [push, pull_request]
|
|
4
|
-
|
|
5
|
-
jobs:
|
|
6
|
-
build:
|
|
7
|
-
runs-on: ubuntu-latest
|
|
8
|
-
strategy:
|
|
9
|
-
matrix:
|
|
10
|
-
ruby:
|
|
11
|
-
- '2.7'
|
|
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
|
-
- 'rails_7.0'
|
|
25
|
-
- 'semantic_logger_3.4'
|
|
26
|
-
- 'semantic_logger_4.6'
|
|
27
|
-
- 'semantic_logger_4.7.0'
|
|
28
|
-
- 'semantic_logger_4.7.2'
|
|
29
|
-
env:
|
|
30
|
-
BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.appraisal }}.gemfile
|
|
31
|
-
steps:
|
|
32
|
-
- uses: actions/checkout@v2
|
|
33
|
-
- uses: zhulik/redis-action@1.1.0
|
|
34
|
-
- uses: ruby/setup-ruby@v1
|
|
35
|
-
with:
|
|
36
|
-
ruby-version: ${{ matrix.ruby }}
|
|
37
|
-
bundler-cache: true
|
|
38
|
-
- run: bundle exec rspec
|