cloudtasker 0.14.0 → 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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/lint_rubocop.yml +1 -1
  3. data/.github/workflows/test_ruby_3.x.yml +19 -18
  4. data/.gitignore +1 -1
  5. data/.rubocop.yml +12 -12
  6. data/Appraisals +18 -20
  7. data/CHANGELOG.md +10 -1
  8. data/Gemfile +1 -1
  9. data/cloudtasker.gemspec +1 -1
  10. data/docs/UNIQUE_JOBS.md +1 -0
  11. data/gemfiles/google_cloud_tasks_1.0.gemfile +1 -1
  12. data/gemfiles/google_cloud_tasks_1.1.gemfile +1 -1
  13. data/gemfiles/google_cloud_tasks_1.2.gemfile +1 -1
  14. data/gemfiles/google_cloud_tasks_1.3.gemfile +1 -1
  15. data/gemfiles/google_cloud_tasks_1.4.gemfile +1 -1
  16. data/gemfiles/google_cloud_tasks_1.5.gemfile +1 -1
  17. data/gemfiles/google_cloud_tasks_2.0.gemfile +1 -1
  18. data/gemfiles/google_cloud_tasks_2.1.gemfile +1 -1
  19. data/gemfiles/rails_6.1.gemfile +3 -1
  20. data/gemfiles/rails_7.0.gemfile +1 -1
  21. data/gemfiles/rails_7.1.gemfile +1 -1
  22. data/gemfiles/{rails_5.2.gemfile → rails_8.0.gemfile} +2 -2
  23. data/gemfiles/{rails_6.0.gemfile → rails_8.1.gemfile} +2 -2
  24. data/gemfiles/semantic_logger_3.4.gemfile +1 -1
  25. data/gemfiles/semantic_logger_4.6.gemfile +1 -1
  26. data/gemfiles/semantic_logger_4.7.0.gemfile +1 -1
  27. data/gemfiles/semantic_logger_4.7.2.gemfile +1 -1
  28. data/lib/cloudtasker/backend/redis_task.rb +1 -1
  29. data/lib/cloudtasker/config.rb +3 -0
  30. data/lib/cloudtasker/redis_client.rb +17 -37
  31. data/lib/cloudtasker/unique_job/lock/until_completed.rb +40 -0
  32. data/lib/cloudtasker/unique_job/middleware.rb +1 -0
  33. data/lib/cloudtasker/version.rb +1 -1
  34. data/lib/cloudtasker/worker_logger.rb +2 -2
  35. metadata +7 -7
  36. 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: 5574bda23d3a128aeb279e7fae03d982cce7788d407d8c627508cb387a1d4d30
4
- data.tar.gz: 24cf8b37d065ce49221d3e118f5579ee8495a09f4ee9be05079536c5c1b497e4
3
+ metadata.gz: 3acbfbd2b8d2ac1c4260b01fc44c4bd43c0061db35eeb84a0bc5f4c1a9358204
4
+ data.tar.gz: 1a9e2d8048b39eac16dc794671796025a16c1f27e95967adde23ad4361be3610
5
5
  SHA512:
6
- metadata.gz: f502740061baf6484214dcd23531521e253bbae1194af88b49623734976fd82b0e0e2762a3f4cc5d1585fd8229f6ae4c1262eadeff82a5e3dc0f1c0154e0880f
7
- data.tar.gz: 4b148a1b8cf1b37c02918cf0d4e442e30e34383578538821815453d53656d8f26c873a6b31914cacde63fba9afddbedb3d263fcd959bbfcd09354f2984e67382
6
+ metadata.gz: 915fb26b5107680819a63cd55d2097f56675779f160eb284e109aacbbd111af358e71e5afc99194ec1846e022a73797f57d5e7b8be7b3b2684cc3b30f0fdc787
7
+ data.tar.gz: 3ca5533216e37a51b2393720d60a6a969ca9c887c0151391f9409921bc952062fd6a82855e9c21b0673a35a604ba40fa56f9f72a590e8481397388c70306ff27
@@ -10,6 +10,6 @@ jobs:
10
10
  - uses: zhulik/redis-action@1.1.0
11
11
  - uses: ruby/setup-ruby@v1
12
12
  with:
13
- ruby-version: '3.3.0'
13
+ ruby-version: "3.3.10"
14
14
  bundler-cache: true
15
15
  - run: bundle exec rubocop
@@ -8,25 +8,26 @@ jobs:
8
8
  strategy:
9
9
  matrix:
10
10
  ruby:
11
- - '3.0'
12
- - '3.1'
13
- - '3.2'
14
- - '3.3'
11
+ - "3.0"
12
+ - "3.1"
13
+ - "3.2"
14
+ - "3.3"
15
+ - "3.4"
15
16
  appraisal:
16
- - 'google_cloud_tasks_1.0'
17
- - 'google_cloud_tasks_1.1'
18
- - 'google_cloud_tasks_1.2'
19
- - 'google_cloud_tasks_1.3'
20
- - 'google_cloud_tasks_1.4'
21
- - 'google_cloud_tasks_1.5'
22
- - 'google_cloud_tasks_2.0'
23
- - 'google_cloud_tasks_2.1'
24
- - 'rails_6.1'
25
- - 'rails_7.0'
26
- - 'semantic_logger_3.4'
27
- - 'semantic_logger_4.6'
28
- - 'semantic_logger_4.7.0'
29
- - 'semantic_logger_4.7.2'
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
@@ -3,7 +3,7 @@
3
3
  /_yardoc/
4
4
  /coverage/
5
5
  /doc/
6
- /examples/rails/log/*.log
6
+ /examples/*/log/*.log
7
7
  /examples/rails/tmp/
8
8
  /gemfiles/*.gemfile.lock
9
9
  /log/
data/.rubocop.yml CHANGED
@@ -3,10 +3,10 @@ require: rubocop-rspec
3
3
  AllCops:
4
4
  NewCops: enable
5
5
  SuggestExtensions: false
6
- TargetRubyVersion: 2.7
6
+ TargetRubyVersion: 3.0
7
7
  Exclude:
8
- - 'gemfiles/**/*'
9
- - 'vendor/**/*'
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
- - 'spec/support/*'
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
- - 'spec/integration/**/*_spec.rb'
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
- - 'spec/**/*'
47
+ - "spec/**/*"
48
48
 
49
49
  Style/Documentation:
50
50
  Exclude:
51
- - 'examples/**/*'
52
- - 'spec/**/*'
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
- - 'examples/rails/config/routes.rb'
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
- - 'examples/**/*'
70
- - 'spec/integration/**/*'
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,33 +32,31 @@ appraise 'google_cloud_tasks_2.1' do
32
32
  gem 'google-cloud-tasks', '~> 2.1.0'
33
33
  end
34
34
 
35
- if RUBY_VERSION < '3'
36
- appraise 'rails_5.2' do
37
- gem 'rails', '~> 5.2.0'
38
- gem 'rspec-rails'
39
- end
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
- appraise 'rails_6.0' do
42
- gem 'rails', '~> 6.0.0'
43
- gem 'rspec-rails'
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 'rails_6.1' do
48
- gem 'rails', '~> 6.1.0'
47
+ appraise 'rails_7.1' do
48
+ gem 'rails', '~> 7.1'
49
49
  gem 'rspec-rails'
50
50
  end
51
51
 
52
- if RUBY_VERSION >= '2.7'
53
- appraise 'rails_7.0' do
54
- gem 'rails', '~> 7.0.0'
55
- gem 'rspec-rails'
56
- end
52
+ appraise 'rails_8.0' do
53
+ gem 'rails', '~> 8.0'
54
+ gem 'rspec-rails'
55
+ end
57
56
 
58
- appraise 'rails_7.1' do
59
- gem 'rails', '~> 7.1'
60
- gem 'rspec-rails'
61
- end
57
+ appraise 'rails_8.1' do
58
+ gem 'rails', '~> 8.1'
59
+ gem 'rspec-rails'
62
60
  end
63
61
 
64
62
  appraise 'semantic_logger_3.4' do
data/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## [v0.15.rc1](https://github.com/keypup-io/cloudtasker/tree/v0.15.rc1) (2025-10-30)
4
+
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
+
3
13
  ## [v0.14.0](https://github.com/keypup-io/cloudtasker/tree/v0.14.0) (2025-02-11)
4
14
 
5
15
  [Full Changelog](https://github.com/keypup-io/cloudtasker/compare/v0.13.2...v0.14.0)
@@ -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
@@ -6,7 +6,7 @@ source 'https://rubygems.org'
6
6
  gemspec
7
7
 
8
8
  # Dev dependencies
9
- gem 'appraisal', github: 'thoughtbot/appraisal'
9
+ gem 'appraisal'
10
10
  gem 'bundler', '~> 2.0'
11
11
  gem 'rake', '>= 12.3.3'
12
12
  gem 'rspec', '~> 3.0'
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 = '>= 2.7.0'
31
+ spec.required_ruby_version = '>= 3.0'
32
32
 
33
33
  spec.add_dependency 'activesupport'
34
34
  spec.add_dependency 'connection_pool'
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
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "appraisal", github: "thoughtbot/appraisal"
5
+ gem "appraisal"
6
6
  gem "bundler", "~> 2.0"
7
7
  gem "rake", ">= 12.3.3"
8
8
  gem "rspec", "~> 3.0"
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "appraisal", github: "thoughtbot/appraisal"
5
+ gem "appraisal"
6
6
  gem "bundler", "~> 2.0"
7
7
  gem "rake", ">= 12.3.3"
8
8
  gem "rspec", "~> 3.0"
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "appraisal", github: "thoughtbot/appraisal"
5
+ gem "appraisal"
6
6
  gem "bundler", "~> 2.0"
7
7
  gem "rake", ">= 12.3.3"
8
8
  gem "rspec", "~> 3.0"
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "appraisal", github: "thoughtbot/appraisal"
5
+ gem "appraisal"
6
6
  gem "bundler", "~> 2.0"
7
7
  gem "rake", ">= 12.3.3"
8
8
  gem "rspec", "~> 3.0"
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "appraisal", github: "thoughtbot/appraisal"
5
+ gem "appraisal"
6
6
  gem "bundler", "~> 2.0"
7
7
  gem "rake", ">= 12.3.3"
8
8
  gem "rspec", "~> 3.0"
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "appraisal", github: "thoughtbot/appraisal"
5
+ gem "appraisal"
6
6
  gem "bundler", "~> 2.0"
7
7
  gem "rake", ">= 12.3.3"
8
8
  gem "rspec", "~> 3.0"
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "appraisal", github: "thoughtbot/appraisal"
5
+ gem "appraisal"
6
6
  gem "bundler", "~> 2.0"
7
7
  gem "rake", ">= 12.3.3"
8
8
  gem "rspec", "~> 3.0"
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "appraisal", github: "thoughtbot/appraisal"
5
+ gem "appraisal"
6
6
  gem "bundler", "~> 2.0"
7
7
  gem "rake", ">= 12.3.3"
8
8
  gem "rspec", "~> 3.0"
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "appraisal", github: "thoughtbot/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: "../"
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "appraisal", github: "thoughtbot/appraisal"
5
+ gem "appraisal"
6
6
  gem "bundler", "~> 2.0"
7
7
  gem "rake", ">= 12.3.3"
8
8
  gem "rspec", "~> 3.0"
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "appraisal", github: "thoughtbot/appraisal"
5
+ gem "appraisal"
6
6
  gem "bundler", "~> 2.0"
7
7
  gem "rake", ">= 12.3.3"
8
8
  gem "rspec", "~> 3.0"
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "appraisal", github: "thoughtbot/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", "~> 5.2.0"
15
+ gem "rails", "~> 8.0"
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", github: "thoughtbot/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", "~> 6.0.0"
15
+ gem "rails", "~> 8.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", github: "thoughtbot/appraisal"
5
+ gem "appraisal"
6
6
  gem "bundler", "~> 2.0"
7
7
  gem "rake", ">= 12.3.3"
8
8
  gem "rspec", "~> 3.0"
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "appraisal", github: "thoughtbot/appraisal"
5
+ gem "appraisal"
6
6
  gem "bundler", "~> 2.0"
7
7
  gem "rake", ">= 12.3.3"
8
8
  gem "rspec", "~> 3.0"
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "appraisal", github: "thoughtbot/appraisal"
5
+ gem "appraisal"
6
6
  gem "bundler", "~> 2.0"
7
7
  gem "rake", ">= 12.3.3"
8
8
  gem "rspec", "~> 3.0"
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "appraisal", github: "thoughtbot/appraisal"
5
+ gem "appraisal"
6
6
  gem "bundler", "~> 2.0"
7
7
  gem "rake", ">= 12.3.3"
8
8
  gem "rspec", "~> 3.0"
@@ -9,7 +9,7 @@ module Cloudtasker
9
9
  class RedisTask
10
10
  attr_reader :id, :http_request, :schedule_time, :retries, :queue, :dispatch_deadline
11
11
 
12
- RETRY_INTERVAL = 20 # seconds
12
+ RETRY_INTERVAL = Config::LOCAL_SERVER_RETRY_DELAY
13
13
 
14
14
  #
15
15
  # Return the Cloudtasker redis client
@@ -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
- if RUBY_VERSION < '3'
136
- #
137
- # Delegate all methods to the redis client.
138
- # Old delegation method.
139
- #
140
- # @param [String, Symbol] name The method to delegate.
141
- # @param [Array<any>] *args The list of method positional arguments.
142
- # @param [Hash<any>] *kwargs The list of method keyword arguments.
143
- # @param [Proc] &block Block passed to the method.
144
- #
145
- # @return [Any] The method return value
146
- #
147
- def method_missing(name, *args, &block)
148
- if Redis.method_defined?(name)
149
- client.with { |c| c.send(name, *args, &block) }
150
- else
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
@@ -14,6 +14,7 @@ require_relative 'lock/no_op'
14
14
  require_relative 'lock/until_executed'
15
15
  require_relative 'lock/until_executing'
16
16
  require_relative 'lock/while_executing'
17
+ require_relative 'lock/until_completed'
17
18
 
18
19
  require_relative 'job'
19
20
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Cloudtasker
4
- VERSION = '0.14.0'
4
+ VERSION = '0.15.rc1'
5
5
  end
@@ -184,9 +184,9 @@ module Cloudtasker
184
184
  #
185
185
  # @return [Any] The method return value
186
186
  #
187
- def method_missing(name, *args, &block)
187
+ def method_missing(name, ...)
188
188
  if logger.respond_to?(name)
189
- logger.send(name, *args, &block)
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.14.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: 2025-02-11 00:00:00.000000000 Z
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,11 +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
156
153
  - gemfiles/rails_7.1.gemfile
154
+ - gemfiles/rails_8.0.gemfile
155
+ - gemfiles/rails_8.1.gemfile
157
156
  - gemfiles/semantic_logger_3.4.gemfile
158
157
  - gemfiles/semantic_logger_4.6.gemfile
159
158
  - gemfiles/semantic_logger_4.7.0.gemfile
@@ -201,6 +200,7 @@ files:
201
200
  - lib/cloudtasker/unique_job/job.rb
202
201
  - lib/cloudtasker/unique_job/lock/base_lock.rb
203
202
  - lib/cloudtasker/unique_job/lock/no_op.rb
203
+ - lib/cloudtasker/unique_job/lock/until_completed.rb
204
204
  - lib/cloudtasker/unique_job/lock/until_executed.rb
205
205
  - lib/cloudtasker/unique_job/lock/until_executing.rb
206
206
  - lib/cloudtasker/unique_job/lock/while_executing.rb
@@ -230,14 +230,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
230
230
  requirements:
231
231
  - - ">="
232
232
  - !ruby/object:Gem::Version
233
- version: 2.7.0
233
+ version: '3.0'
234
234
  required_rubygems_version: !ruby/object:Gem::Requirement
235
235
  requirements:
236
236
  - - ">="
237
237
  - !ruby/object:Gem::Version
238
238
  version: '0'
239
239
  requirements: []
240
- rubygems_version: 3.5.4
240
+ rubygems_version: 3.5.22
241
241
  signing_key:
242
242
  specification_version: 4
243
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