belated 0.6.0 → 0.6.4

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: 4ca7f7d0a3a78ca41e6ba3afed7630e1ac72d4a88c4fdea08604066518c843a6
4
- data.tar.gz: 2fb05c90501681f9f45ab4476cbdc4c1ac88de9addafaa1c54da0a16731426df
3
+ metadata.gz: 535f6d7f0af3565867c6f621fb328966d35ff524e38ffc22813e4410fd66eb2f
4
+ data.tar.gz: ace8cc58b9519d07e7bce2f12c5b1e45eba570f75a0a5f34b0496a5acfac679d
5
5
  SHA512:
6
- metadata.gz: 5182420208c866b37511bda56cc5a2e8fddac8d87a23274923318f576b66f3d3848b33c6633296bbfed088e6bd339a458e92ccc057a63c8a815dfaf12aa3fdf7
7
- data.tar.gz: 78ef5824e2afdd45910dbe81e79e54986dcc2c7ccf346515228c978a55c5d2aa0d0f29c4d894e219667ee6d6b735fbef43c94b61bd36d645a3e9ca1152bf6a86
6
+ metadata.gz: '058ed5f47971a9f39d7ec39997f23bdfeb54221b516ee9162330e9a0c783dc9ec6d7633ad029b7d96792e08bd317d5efced10ca2ea97b0e8322507a6e5f9a045'
7
+ data.tar.gz: c5ef2e3ad64ecda5e1fa2cb0feab2dda1b50388a523e571fe3be829af76e864973429bb95d0433353dd5a58bf97f2f366d19bd19a7ae0d6d578030646156f542
data/.rubocop.yml CHANGED
@@ -37,6 +37,9 @@ Style/BlockDelimiters:
37
37
  Style/ModuleFunction:
38
38
  EnforcedStyle: extend_self
39
39
 
40
+ Metrics/AbcSize:
41
+ Max: 17
42
+
40
43
  Metrics/BlockLength:
41
44
  Exclude:
42
45
  - 'spec/**/*.rb'
data/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.6.4] - 2021-08-22
4
+ - Inline jobs for testing!
5
+ ```ruby
6
+ `belated/testing`
7
+ Belated::Testing.inline!
8
+ ```
9
+ - Very much inspired by how Sidekiq is doing this.
10
+ - Read more in the testing part of README.md
11
+
12
+ ## [0.6.3] - 2021-08-21
13
+
14
+ - Needed to have the hash inside the mutex when going over it; otherwise you still the get can't add key into hash during iteration error. Of course.
15
+
16
+ ## [0.6.2] - 2021-08-20
17
+
18
+ - Use a mutex for the proc_table used by the client. Fixes
19
+ `RuntimeError: can't add a new key into hash during iteration (Most recent call first)`, so starting improving thread safety with this fix.
20
+
21
+ ## [0.6.1] - 2021-08-20
22
+
23
+ When the client closes and worker has a reference to a proc, a `DRb::ConnError` is raised. Rescueing it and ignoring it.
3
24
  ## [0.6.0] - 2021-08-19
4
25
 
5
26
  - Only need to keep references on the client side for procs. Not needed for classes, as they are pass-by-value. However, you can only pass procs by reference, so need to keep track of them. They're removed from the client side when they're completed though.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- belated (0.6.0)
4
+ belated (0.6.4)
5
5
  drb
6
6
  dry-configurable
7
7
  sorted_set
data/README.md CHANGED
@@ -14,15 +14,14 @@ Note that currently the timezone is hardcoded to UTC.
14
14
 
15
15
  Can be used with or without Rails.
16
16
 
17
+ Can be used if you're on a normal instance such as EC2 or Digital Ocean drop. Not if you're on a Heroku or Docker, or anything with ephemeral storage.
18
+
17
19
  TODO LIST:
18
20
 
19
- - Use GDBM for queue storage? That way could maybe get rid of YAML dumping and make things a bit safer. Not ordered though, so maybe keep a list of the jobs as YAML and update it sometimes? Just as backup.
20
- - Rescue `DRb::DRbRemoteError` when shutting down, might not need to if using GDBM?
21
- - Don't use class instance variables.
21
+ - Use GDBM for queue storage? That way could maybe get rid of YAML dumping and make things a bit safer. Not ordered though, so maybe keep a list of the jobs as YAML and update it sometimes? Just as backup. Or RocksDB? Would need to be configurable if you don't have something installed.
22
22
  - Make DRb port configurable.
23
- - Don't hardcode timezone.
23
+ - Don't hardcode timezone to UTC.
24
24
  - Add some checks to the client for proper jobs.
25
- - Have multiple queues?
26
25
  - Maybe support ActiveJob?
27
26
  - Have a web UI.
28
27
  - Have a job history
@@ -140,6 +139,22 @@ Path to Rails project.
140
139
 
141
140
  Number of workers.
142
141
 
142
+ ## Testing
143
+
144
+ When testing, you can require `belated/testing` and then call `Belated::Testing.inline!` to make your jobs perform inline.
145
+
146
+ ```ruby
147
+ `belated/testing`
148
+ c = Belated::Client.instance
149
+ c.start
150
+ c.perform(proc { 2/ 1}) # Tries to push the job to the drb backend
151
+ # <Belated::JobWrapper:0x00005654bc2db1f0 @at=nil, @completed=false, @id="95e4dc6a-1876-4adf-ae0f-5ae902f5f024", @job=#<Proc:0x00005654bc2db330 (irb):3>, @max_retries=5, @proc_klass=true, @retries=0>
152
+ Belated::Testing.inline! # Sidekiq-inspired, now jobs run inline
153
+ c.perform(proc { 2/ 1}) # Returns 2 right away
154
+ # 2
155
+ Belated::Client.test_mode_off! # Turn off inline job processing
156
+ ```
157
+
143
158
  ## Development
144
159
 
145
160
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/lib/belated.rb CHANGED
@@ -29,7 +29,7 @@ class Belated
29
29
  setting :rails_path, '.'
30
30
  setting :workers, 1
31
31
  setting :connect, true
32
- setting :environment, 'development'
32
+ setting :environment, 'development', reader: true
33
33
  setting :logger, Logger.new($stdout), reader: true
34
34
  setting :log_level, :info, reader: true
35
35
 
@@ -16,12 +16,15 @@ class Belated
16
16
  # Connects to the queue through DRb.
17
17
  # @return [void]
18
18
  def start
19
+ return if started?
20
+
19
21
  server_uri = Belated::URI
20
22
  DRb.start_service
21
23
  self.proc_table = {}
22
24
  self.bank = Thread::Queue.new
23
25
  self.queue = DRbObject.new_with_uri(server_uri)
24
26
  @started = true
27
+ @mutex = Mutex.new
25
28
  end
26
29
  alias initialize start
27
30
 
@@ -29,32 +32,41 @@ class Belated
29
32
  @started
30
33
  end
31
34
 
35
+ # Makes it possible to reset the client
36
+ def turn_off
37
+ @started = false
38
+ banker_thread&.kill
39
+ end
40
+
32
41
  # Thread in charge of handling the bank queue.
33
42
  # You probably want to memoize the client in order to avoid
34
43
  # having many threads in the sleep state.
35
44
  # @return [void]
36
45
  def start_banker_thread
37
- self.banker_thread = Thread.new do
46
+ Thread.new do
38
47
  loop do
39
48
  delete_from_table
40
- if bank.empty?
41
- sleep 10
42
- next
43
- end
44
- begin
45
- queue.push(wrapper = bank.pop)
46
- rescue DRb::DRbConnError
47
- bank.push(wrapper)
49
+ sleep 10 and next if bank.empty?
50
+
51
+ until bank.empty?
52
+ begin
53
+ queue.push(wrapper = bank.pop)
54
+ rescue DRb::DRbConnError
55
+ bank.push(wrapper)
56
+ sleep 5
57
+ end
48
58
  end
49
59
  end
50
60
  end
51
61
  end
52
62
 
53
63
  def delete_from_table
54
- return if proc_table.empty?
64
+ return if proc_table.length < 25
55
65
 
56
- proc_table.select { |_k, v| v.completed }.each do |key, _value|
57
- proc_table.delete(key)
66
+ @mutex.synchronize do
67
+ proc_table.select { |_k, v| v.completed }.each do |key, _value|
68
+ proc_table.delete(key)
69
+ end
58
70
  end
59
71
  end
60
72
 
@@ -65,16 +77,14 @@ class Belated
65
77
  # @param max_retries [Integer] - Times the job should be retried if it fails.
66
78
  # @return [JobWrapper] - The job wrapper for the queue.
67
79
  def perform(job, at: nil, max_retries: 5)
68
- log 'Passing a proc and at time is deprecated and will be removed in 0.6' if job.instance_of?(Proc) && !at.nil?
80
+ log 'Call .start on the client instance first!' unless started?
69
81
 
70
- job_wrapper = if job.is_a?(JobWrapper)
71
- job
72
- else
73
- JobWrapper.new(job: job, at: at, max_retries: max_retries)
74
- end
82
+ job_wrapper = wrap_job(job, at: at, max_retries: max_retries)
75
83
  bank.push(job_wrapper)
76
- proc_table[job_wrapper.object_id] = job_wrapper if job_wrapper.proc_klass
77
- start_banker_thread if banker_thread.nil?
84
+ @mutex.synchronize do
85
+ proc_table[job_wrapper.object_id] = job_wrapper if job_wrapper.proc_klass
86
+ end
87
+ self.banker_thread = start_banker_thread if banker_thread.nil?
78
88
  job_wrapper
79
89
  end
80
90
  alias perform_belated perform
@@ -82,6 +92,12 @@ class Belated
82
92
 
83
93
  private
84
94
 
95
+ def wrap_job(job, at:, max_retries:)
96
+ return job if job.is_a?(JobWrapper)
97
+
98
+ JobWrapper.new(job: job, at: at, max_retries: max_retries)
99
+ end
100
+
85
101
  def drb_connected?
86
102
  queue.connected?
87
103
  rescue StandardError
@@ -0,0 +1,37 @@
1
+ class Belated
2
+ # Testing helpers
3
+ # Enable or disable testing
4
+ class Testing
5
+ @@testing = false
6
+
7
+ def self.inline?
8
+ @@testing == true
9
+ end
10
+
11
+ def self.inline!
12
+ @@testing = true
13
+ end
14
+
15
+ def self.test_mode_off!
16
+ @@testing = false
17
+ end
18
+ end
19
+ end
20
+
21
+ class Belated
22
+ # A client that can perform jobs inline
23
+ class Client
24
+ alias old_perform perform
25
+ def perform(job, at: nil, max_retries: 5)
26
+ if Belated::Testing.inline?
27
+ if job.respond_to?(:call)
28
+ job.call
29
+ else
30
+ job.perform
31
+ end
32
+ else
33
+ old_perform(job, at: at, max_retries: max_retries)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Belated
4
- VERSION = '0.6.0'
4
+ VERSION = '0.6.4'
5
5
  end
@@ -20,7 +20,7 @@ class Belated
20
20
 
21
21
  log "Worker #{@number} got job: #{job.inspect}"
22
22
  log job.perform
23
- rescue Errno::ECONNREFUSED, RangeError => e
23
+ rescue DRb::DRbConnError, Errno::ECONNREFUSED, RangeError => e
24
24
  log e
25
25
  end
26
26
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: belated
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.6.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sampo Kuokkanen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-19 00:00:00.000000000 Z
11
+ date: 2021-08-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: drb
@@ -99,6 +99,7 @@ files:
99
99
  - lib/belated/logging.rb
100
100
  - lib/belated/queue.rb
101
101
  - lib/belated/rails.rb
102
+ - lib/belated/testing.rb
102
103
  - lib/belated/version.rb
103
104
  - lib/belated/worker.rb
104
105
  homepage: https://github.com/sampokuokkanen/belated