background_job 0.0.1.rc1 → 0.0.1.rc3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7073c14e1fd364a96f5f4ddc812c5d67921905307af97f85bc3d8a0173304093
4
- data.tar.gz: 95f18748a479ffa52bf39ac94830080564a95223193c8655c59a36083b6eebc7
3
+ metadata.gz: 85008658f92ee38b57dc2dd7692c7b905ee97096907f97aef166f14a605e34b7
4
+ data.tar.gz: 19c2cba85992b54d9d1b7d5c080e884cb859a3c78b561d303145905850cab63a
5
5
  SHA512:
6
- metadata.gz: aa43df351a913191022dc34d5773ec51ab80bfbdf575cad58c1d33845150fa75a443f3e394e00b46da3283f7e0e69a7ed86b4637ef6e2e960ff797021172758f
7
- data.tar.gz: c78f2257f401f3d9585f210007cb314da943aaa971dd396cccee703e142d1c949e1c037a8fcbb20bb3e8a623b7db0e36b6feb4fd25f1b42338669913465dfe4b
6
+ metadata.gz: 02d6a213cc6a3d1f2e35806c4b9078eb5a8cbbf4e1cdbfbbad1f472ab8dd1ba17b4a37892f61ce0fccf63839b1c5e664b302ecd0acbbd30cedb6528a8b2a27cc
7
+ data.tar.gz: 0fd818b7983a7762a2b6f810b76cf07f4e01e0e5cfbeb9d63c3c130f2feb45c04c2384d00f944492c1cd29d7d526b3cc3e72ffba5262d51546c938455e0ce2c2
data/Gemfile.lock CHANGED
@@ -1,8 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- background_job (0.0.1.rc1)
5
- connection_pool
4
+ background_job (0.0.1.rc3)
6
5
  multi_json
7
6
  redis
8
7
 
@@ -22,7 +21,7 @@ GEM
22
21
  coderay (~> 1.1)
23
22
  method_source (~> 1.0)
24
23
  rake (12.3.3)
25
- redis (5.2.0)
24
+ redis (5.3.0)
26
25
  redis-client (>= 0.22.0)
27
26
  redis-client (0.22.2)
28
27
  connection_pool
@@ -34,6 +34,5 @@ Gem::Specification.new do |spec|
34
34
  spec.require_paths = ['lib']
35
35
 
36
36
  spec.add_dependency 'redis', '>= 0.0.0'
37
- spec.add_dependency 'connection_pool', '>= 0.0.0'
38
37
  spec.add_dependency 'multi_json', '>= 0.0.0'
39
38
  end
data/docker-compose.yml CHANGED
@@ -1,6 +1,5 @@
1
1
  services:
2
2
  redis:
3
3
  image: redis
4
- command: redis-server
5
4
  ports:
6
5
  - 6379:6379
@@ -19,5 +19,17 @@ module BackgroundJob
19
19
  @redis_pool = nil
20
20
  @redis = value
21
21
  end
22
+
23
+ def update_queues!
24
+ redis_pool.with do |conn|
25
+ indexing_queues = jobs.values.map { |job| job[:queue] }.uniq
26
+ key = [namespace, 'queues'].compact.join(':')
27
+ conn.pipelined do |pipeline|
28
+ indexing_queues.each do |queue|
29
+ pipeline.sadd?(key, queue)
30
+ end
31
+ end
32
+ end
33
+ end
22
34
  end
23
35
  end
@@ -16,6 +16,14 @@ module BackgroundJob
16
16
  class Configuration
17
17
  attr_reader :redis
18
18
 
19
+ def reset!
20
+ @redis = nil
21
+ @redis_pool = nil
22
+ @services = nil
23
+ @faktory = nil
24
+ @sidekiq = nil
25
+ end
26
+
19
27
  def redis=(value)
20
28
  @redis_pool = nil
21
29
  @redis = value
@@ -26,18 +26,21 @@ module BackgroundJob
26
26
  # * Otherwise enqueue for immediate execution
27
27
  #
28
28
  # @return [Hash] Payload that was sent to redis
29
- def push
29
+ def push(**kwargs)
30
30
  normalize_before_push!
31
31
 
32
+ kwargs[:retry] ||= 3 # retry is a reserved keyword
32
33
  BackgroundJob.config.sidekiq.middleware.invoke(self, :sidekiq) do
33
- # Optimization to enqueue something now that is scheduled to go out now or in the past
34
- if (timestamp = payload.delete('at')) && (timestamp > Time.now.to_f)
35
- redis_pool.with do |redis|
36
- redis.zadd(scheduled_queue_name, timestamp.to_f.to_s, to_json(payload))
37
- end
38
- else
39
- redis_pool.with do |redis|
40
- redis.lpush(immediate_queue_name, to_json(payload))
34
+ retriable_connection(max_attempts: kwargs[:retry]) do |conn|
35
+ # Optimization to enqueue something now that is scheduled to go out now or in the past
36
+ if (timestamp = payload.delete('at')) && (timestamp > Time.now.to_f)
37
+ conn.zadd(scheduled_queue_name, timestamp.to_f.to_s, to_json(payload))
38
+ else
39
+ payload['enqueued_at'] = Time.now.to_f
40
+ conn.pipelined do |pipeline|
41
+ pipeline.sadd(queues_set_name, [queue_name])
42
+ pipeline.lpush(immediate_queue_name, to_json(payload))
43
+ end
41
44
  end
42
45
  end
43
46
  payload
@@ -48,7 +51,6 @@ module BackgroundJob
48
51
 
49
52
  def normalize_before_push!
50
53
  with_job_jid # Generate a unique job id
51
- payload['enqueued_at'] = Time.now.to_f
52
54
  end
53
55
 
54
56
  def redis_pool
@@ -64,12 +66,34 @@ module BackgroundJob
64
66
  end
65
67
 
66
68
  def immediate_queue_name
67
- [namespace, 'queue', payload.fetch('queue')].compact.join(':')
69
+ [namespace, 'queue', queue_name].compact.join(':')
70
+ end
71
+
72
+ def queues_set_name
73
+ [namespace, 'queues'].compact.join(':')
74
+ end
75
+
76
+ def queue_name
77
+ payload.fetch('queue')
68
78
  end
69
79
 
70
80
  def to_json(value)
71
81
  MultiJson.dump(value, mode: :compat)
72
82
  end
83
+
84
+ def retriable_connection(max_attempts: 3)
85
+ tries = 0
86
+ redis_pool.with do |conn|
87
+ yield conn
88
+ rescue Redis::CommandError => ex
89
+ if ex.message =~ /READONLY|NOREPLICAS|UNBLOCKED/ && tries < max_attempts
90
+ tries += 1
91
+ conn.close
92
+ retry
93
+ end
94
+ raise ex
95
+ end
96
+ end
73
97
  end
74
98
  end
75
99
  end
@@ -28,15 +28,16 @@ module BackgroundJob
28
28
  end
29
29
 
30
30
  class Builder < Module
31
- def initialize(**options)
31
+ def initialize(native: false, **options)
32
+ @native = native
32
33
  @runtime_mod = Module.new do
33
34
  define_method(:background_job_user_options) { options }
34
35
  end
35
36
  end
36
37
 
37
38
  def extended(base)
38
- base.include(::Faktory::Job) if defined?(::Faktory)
39
- base.extend BackgroundJob::Mixin::SharedInterface
39
+ base.include(::Faktory::Job) if defined?(::Faktory::Job)
40
+ base.extend(BackgroundJob::Mixin::SharedInterface) unless @native
40
41
  base.extend ClassMethods
41
42
  base.extend @runtime_mod
42
43
  end
@@ -33,15 +33,20 @@ module BackgroundJob
33
33
  end
34
34
 
35
35
  class Builder < Module
36
- def initialize(**options)
36
+ def initialize(native: false, **options)
37
+ @native = native
37
38
  @runtime_mod = Module.new do
38
39
  define_method(:background_job_user_options) { options }
39
40
  end
40
41
  end
41
42
 
42
43
  def extended(base)
43
- base.include(::Sidekiq::Worker) if defined?(::Sidekiq)
44
- base.extend BackgroundJob::Mixin::SharedInterface
44
+ if defined?(::Sidekiq::Job)
45
+ base.include(::Sidekiq::Job)
46
+ elsif defined?(::Sidekiq::Worker)
47
+ base.include(::Sidekiq::Worker)
48
+ end
49
+ base.extend(BackgroundJob::Mixin::SharedInterface) unless @native
45
50
  base.extend ClassMethods
46
51
  base.extend @runtime_mod
47
52
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BackgroundJob
4
- VERSION = '0.0.1.rc1'
4
+ VERSION = '0.0.1.rc3'
5
5
  end
@@ -42,13 +42,21 @@ module BackgroundJob
42
42
  faktory: 'Faktory',
43
43
  }.freeze
44
44
 
45
- SERVICES.each do |id, name|
46
- define_singleton_method(id) do |job_name, **options|
47
- Jobs.const_get(name).new(job_name, **options)
45
+ def self.job(service, job_name, **options)
46
+ service = service.to_sym
47
+ unless SERVICES.key?(service)
48
+ raise Error, "Service `#{service}' is not supported. Supported services are: #{SERVICES.keys.join(', ')}"
49
+ end
50
+ Jobs.const_get(SERVICES[service]).new(job_name, **options)
51
+ end
52
+
53
+ SERVICES.each do |service_name, _const_name|
54
+ define_singleton_method(service_name) do |job_name, **options|
55
+ job(service_name, job_name, **options)
48
56
  end
49
57
  end
50
58
 
51
- def self.mixin(service, **options)
59
+ def self.mixin(service, native: false, **options)
52
60
  service = service.to_sym
53
61
  unless SERVICES.key?(service)
54
62
  raise Error, "Service `#{service}' is not supported. Supported services are: #{SERVICES.keys.join(', ')}"
@@ -58,7 +66,7 @@ module BackgroundJob
58
66
 
59
67
  module_name = service.to_s.split(/_/i).collect!{ |w| w.capitalize }.join
60
68
  mod = Mixin.const_get(module_name)
61
- mod::Builder.new(**options)
69
+ mod::Builder.new(native: native, **options)
62
70
  end
63
71
 
64
72
  def self.jid
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: background_job
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.rc1
4
+ version: 0.0.1.rc3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marcos G. Zimmermann
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-08-14 00:00:00.000000000 Z
11
+ date: 2024-08-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
@@ -24,20 +24,6 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.0.0
27
- - !ruby/object:Gem::Dependency
28
- name: connection_pool
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: 0.0.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.0.0
41
27
  - !ruby/object:Gem::Dependency
42
28
  name: multi_json
43
29
  requirement: !ruby/object:Gem::Requirement