belated 0.5.5 → 0.5.6

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: 94a7f0ce2c6f7c80dfe5b8410c72dac95dbc709937361b36aa7eaeea091d8cfb
4
- data.tar.gz: da41ab683e0a2729b1dc1e7228592e91a0d259cc46bbaf6ef4a2186abb379330
3
+ metadata.gz: 0ae6d21b68590fe6edb5ed817c1dd0806dadf5ee7320955cc3f4f652969f6501
4
+ data.tar.gz: 744ab565ddd144e5562ba39f675416e3dd17154b4ab70c916443d2711c148311
5
5
  SHA512:
6
- metadata.gz: cacbed28173905bf3fd5489bb8797abecfe4402096cea5d068dcec5a3bf27d9d5c1d048c7d9cc159aedef9cda981a038f4177d6ccd3648c87752d2bedb94390d
7
- data.tar.gz: f92f505a4d8a53c13b4411ae611d5584377f09b31f8e33f9f39a1daf77b3684b977e3c01a472a654c4c07251a1e0aba6fc2f9953eb7383ef1c15fd7be2385e33
6
+ metadata.gz: b1baddc3b1a949af6420e6925e6e3b1565d006684d59333d89334f2e298c3f3eccdf0347402035417ee4faa300e643b4fc6824049cebabf8dab53fb2a49d0cf6
7
+ data.tar.gz: 065cd54c037f481a5d91a2da1800a721d40aceba6881315d261022b77d29898e6b738e72c885ef3876c6e8552fd2303a1b08270361fc624162c11c3b3b720ac2
@@ -10,7 +10,8 @@ jobs:
10
10
  - name: Set up Ruby
11
11
  uses: ruby/setup-ruby@v1
12
12
  with:
13
- ruby-version: 3.0.1
13
+ ruby-version: 3.0.2
14
14
  bundler-cache: true
15
+ cache-version: 1
15
16
  - name: Run the default task
16
17
  run: bundle exec rake
data/.rubocop.yml CHANGED
@@ -1,7 +1,12 @@
1
- require: rubocop-performance
2
1
  AllCops:
3
2
  TargetRubyVersion: 2.7
4
3
  NewCops: enable
4
+ Exclude:
5
+ - 'dummy/**/*'
6
+ - 'vendor/**/*'
7
+
8
+ Lint/HashCompareByIdentity:
9
+ Enabled: false
5
10
 
6
11
  Style/StringLiterals:
7
12
  Enabled: true
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  ## [Unreleased]
2
2
 
3
+
4
+ ## [0.5.6] - 2021-08-17
5
+
6
+ - Now the client has a hash table that holds references to the objects you push through it. This is to get by GC, otherwise the objects are collected on clientside, but are still referenced on server side. This means that you do not want to use two instances of Client at the same time. Also, might need to write a way to close the client...
7
+ - Should work a bit more safely now! Performance testing 0.5.5 online using a Rails project, it performed horribly, so it should be a bit better now.
3
8
  ## [0.5.5] - 2021-08-15
4
9
 
5
10
  - Use SortedSet for future jobs, to avoid having to go through the whole list every few seconds.
data/Gemfile CHANGED
@@ -13,6 +13,6 @@ gem 'database_cleaner-active_record'
13
13
  gem 'rails', '>= 6.1.3'
14
14
  gem 'rspec-rails'
15
15
  gem 'rubocop', '~> 1.7'
16
- gem 'rubocop-performance', require: false
16
+ gem 'rubocop-discourse'
17
17
  gem 'sqlite3'
18
18
  gem 'stackprof'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- belated (0.5.5)
4
+ belated (0.5.6)
5
5
  drb
6
6
  dry-configurable
7
7
  sorted_set
@@ -160,20 +160,23 @@ GEM
160
160
  rspec-mocks (~> 3.10)
161
161
  rspec-support (~> 3.10)
162
162
  rspec-support (3.10.2)
163
- rubocop (1.18.3)
163
+ rubocop (1.19.0)
164
164
  parallel (~> 1.10)
165
165
  parser (>= 3.0.0.0)
166
166
  rainbow (>= 2.2.2, < 4.0)
167
167
  regexp_parser (>= 1.8, < 3.0)
168
168
  rexml
169
- rubocop-ast (>= 1.7.0, < 2.0)
169
+ rubocop-ast (>= 1.9.1, < 2.0)
170
170
  ruby-progressbar (~> 1.7)
171
171
  unicode-display_width (>= 1.4.0, < 3.0)
172
- rubocop-ast (1.7.0)
172
+ rubocop-ast (1.10.0)
173
173
  parser (>= 3.0.1.1)
174
- rubocop-performance (1.11.4)
175
- rubocop (>= 1.7.0, < 2.0)
176
- rubocop-ast (>= 0.4.0)
174
+ rubocop-discourse (2.4.2)
175
+ rubocop (>= 1.1.0)
176
+ rubocop-rspec (>= 2.0.0)
177
+ rubocop-rspec (2.4.0)
178
+ rubocop (~> 1.0)
179
+ rubocop-ast (>= 1.1.0)
177
180
  ruby-progressbar (1.11.0)
178
181
  set (1.0.1)
179
182
  sorted_set (1.0.3)
@@ -209,7 +212,7 @@ DEPENDENCIES
209
212
  rspec (~> 3.0)
210
213
  rspec-rails
211
214
  rubocop (~> 1.7)
212
- rubocop-performance
215
+ rubocop-discourse
213
216
  sqlite3
214
217
  stackprof
215
218
 
data/README.md CHANGED
@@ -16,7 +16,7 @@ Can be used with or without Rails.
16
16
 
17
17
  TODO LIST:
18
18
 
19
- - Use GDBM for queeue storage? That way could maybe get rid of YAML dumping and make things a bit safer.
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
20
  - Rescue `DRb::DRbRemoteError` when shutting down, might not need to if using GDBM?
21
21
  - Don't use class instance variables.
22
22
  - Make DRb port configurable.
@@ -29,7 +29,7 @@ TODO LIST:
29
29
  - Do some performance testing.
30
30
  - Deploy a Rails app to production that is using Belated
31
31
  and mention it in the readme. (Capistrano support?)
32
- ([Wasurechatta](wasurechatta.com))
32
+ ([Wasurechatta](https://wasurechatta.com/))
33
33
  - Add a section telling people to use Sidekiq if they can
34
34
 
35
35
  ## Installation
@@ -104,7 +104,9 @@ If you don't want the job to run right away, you can also pass it a keyword para
104
104
  client.perform_belated(job, Time.now + 1.month)
105
105
  ```
106
106
 
107
- Note that you probably want to memoize the client, as it always creates a 'banker thread' now if you have no connection and there is the overhead of connecting to dRuby. Maybe even use it as a global!(`$client`)
107
+ Note that you probably want to memoize the client, as it always creates a 'banker thread' and there is the overhead of connecting to dRuby. Maybe even use it as a global!(`$client`).
108
+
109
+ The client also holds references to the jobs that have been pushed so that they are not collected by GC.
108
110
 
109
111
  # Settings
110
112
 
data/lib/belated.rb CHANGED
@@ -92,7 +92,7 @@ class Belated
92
92
  log 'starting future jobs thread'
93
93
  loop do
94
94
  sleep 0.1
95
- job = @@queue.future_jobs.at(0)
95
+ job = @@queue.future_jobs.min
96
96
  if job.nil?
97
97
  sleep 5
98
98
  next
@@ -7,7 +7,7 @@ class Belated
7
7
  # client = Belated::Client.new
8
8
  # client.enqueue(JubJub.new, at: Time.now + 5.seconds)
9
9
  class Client
10
- attr_accessor :queue, :bank, :banker_thread
10
+ attr_accessor :queue, :bank, :banker_thread, :table
11
11
 
12
12
  # Starts up the client.
13
13
  # Connects to the queue through DRb.
@@ -15,8 +15,10 @@ class Belated
15
15
  def initialize
16
16
  server_uri = Belated::URI
17
17
  DRb.start_service
18
+ self.table = {}
18
19
  self.bank = Thread::Queue.new
19
20
  self.queue = DRbObject.new_with_uri(server_uri)
21
+ start_banker_thread
20
22
  end
21
23
 
22
24
  # Thread in charge of handling the bank queue.
@@ -27,18 +29,26 @@ class Belated
27
29
  self.banker_thread = Thread.new do
28
30
  loop do
29
31
  sleep 0.01
30
- unless drb_connected?
31
- sleep(10)
32
- next
33
- end
34
32
 
35
- job = bank.pop
33
+ delete_from_table
36
34
 
37
- perform(job)
35
+ if bank.empty?
36
+ sleep 10
37
+ else
38
+ perform(bank.pop)
39
+ end
38
40
  end
39
41
  end
40
42
  end
41
43
 
44
+ def delete_from_table
45
+ return if table.empty?
46
+
47
+ table.select { |_k, v| v.completed }.each do |key, _value|
48
+ table.delete(key)
49
+ end
50
+ end
51
+
42
52
  # The method that pushes the jobs to the queue.
43
53
  # If there is no connection, it pushes the job to the bank.
44
54
  # @param job [Object] - The the job to be pushed.
@@ -46,16 +56,17 @@ class Belated
46
56
  # @param max_retries [Integer] - Times the job should be retried if it fails.
47
57
  # @return [JobWrapper] - The job wrapper for the queue.
48
58
  def perform(job, at: nil, max_retries: 5)
59
+ log 'Passing a proc and at time is deprecated and will be removed in 0.6' if job.instance_of?(Proc) && !at.nil?
60
+
49
61
  job_wrapper = if job.is_a?(JobWrapper)
50
62
  job
51
63
  else
52
64
  JobWrapper.new(job: job, at: at, max_retries: max_retries)
53
65
  end
54
- pp queue.push(job_wrapper)
55
- job_wrapper
66
+ queue.push(job_wrapper)
67
+ table[job_wrapper.object_id] = job_wrapper
56
68
  rescue DRb::DRbConnError
57
69
  bank.push(job_wrapper)
58
- start_banker_thread if banker_thread.nil?
59
70
  end
60
71
  alias perform_belated perform
61
72
  alias perform_later perform
@@ -2,10 +2,18 @@ require 'securerandom'
2
2
  require_relative 'logging'
3
3
 
4
4
  class Belated
5
+ # JobWrapper is a wrapper for a job. It is responsible for
6
+ # - logging
7
+ # - error handling
8
+ # - job execution
9
+ # - job result handling
10
+ # - job result logging
11
+ # - job retries
12
+ # - job retry delay
5
13
  class JobWrapper
6
14
  include Comparable
7
15
  include Logging
8
- attr_accessor :retries, :max_retries, :id, :job, :at
16
+ attr_accessor :retries, :max_retries, :id, :job, :at, :completed
9
17
 
10
18
  def initialize(job:, max_retries: 5, at: nil)
11
19
  self.retries = 0
@@ -13,19 +21,22 @@ class Belated
13
21
  self.id = SecureRandom.uuid
14
22
  self.job = job
15
23
  self.at = at
24
+ self.completed = false
16
25
  end
17
26
 
18
- def <=>(another)
19
- at <=> another.at
27
+ def <=>(other)
28
+ at <=> other.at
20
29
  end
21
30
 
22
31
  # rubocop:disable Lint/RescueException
23
32
  def perform
24
- if job.respond_to?(:call)
25
- job.call
26
- else
27
- job.perform
28
- end
33
+ resp = if job.respond_to?(:call)
34
+ job.call
35
+ else
36
+ job.perform
37
+ end
38
+ self.completed = true
39
+ resp
29
40
  rescue Exception => e
30
41
  case e.class
31
42
  when Interrupt, SignalException
@@ -1,4 +1,6 @@
1
1
  class Belated
2
+ # Logger for Belated.
3
+ # Include this module in your class to get a logger.
2
4
  module Logging
3
5
  extend self
4
6
 
data/lib/belated/queue.rb CHANGED
@@ -6,6 +6,11 @@ require 'belated/job_wrapper'
6
6
  require 'sorted_set'
7
7
 
8
8
  class Belated
9
+ # Job queues that Belated uses.
10
+ # queue is the jobs that are currenly
11
+ # waiting for a worker to start working on them.
12
+ # future_jobs is a SortedSet of jobs that are going
13
+ # to be added to queue at some point in the future.
9
14
  class Queue
10
15
  include Logging
11
16
  attr_accessor :future_jobs
@@ -81,7 +86,7 @@ class Belated
81
86
  private
82
87
 
83
88
  def proc_or_shutdown?(job)
84
- job.job.instance_of?(Proc) || job.is_a?(Symbol)
89
+ job.is_a?(Symbol) || job.job.instance_of?(Proc)
85
90
  end
86
91
  end
87
92
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class Belated
4
- VERSION = '0.5.5'
4
+ VERSION = '0.5.6'
5
5
  end
@@ -19,7 +19,9 @@ class Belated
19
19
  break if job.is_a?(Symbol)
20
20
 
21
21
  log "Worker #{@number} got job: #{job.inspect}"
22
- job.perform
22
+ log job.perform
23
+ rescue RangeError => e
24
+ log e
23
25
  end
24
26
  end
25
27
  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.5.5
4
+ version: 0.5.6
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-15 00:00:00.000000000 Z
11
+ date: 2021-08-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: drb