midget_jobs 0.1.7 → 0.2.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: badc2c01c840c608fe03888ce13dbcee759869434fd0680a86de4159bd6b4bc0
4
- data.tar.gz: 14105778bd73b54cf1235851526b2f3dd1db14839ab035440b1a6e389641a915
3
+ metadata.gz: 48a48a20bf9bb5ba396ec2f468c15fbcb6ac6d007c52ae8980fede79d7b91ad2
4
+ data.tar.gz: d2e1a91c7327de1fe53e60143867fe215e913c83d0763f113a3b66c13b6acbfa
5
5
  SHA512:
6
- metadata.gz: 35600f3e2a92a3a82c7ec24bda01a1048940210dde6e720cb1e1530eb919bb9e24d6b13dcecbc8c089cb502fc73f96666c6ba10cb65723b13c30aa65f0572186
7
- data.tar.gz: 843cdf6edf6ed6642268a9b3bfac336ef5ecea2c44b7f9218afde528719ec86d1055b867558935ca8679fa0191f55eb817c6d9abe453502e3b4a64bdeb4a4ba0
6
+ metadata.gz: '05855d4770375c491f6c887a5a8ed2e37295fb68ef760dff0bbc841547db5cc42fa9c3a33985cddd738c6dc8e505c846efbd8173253555567b91780fb99f8f44'
7
+ data.tar.gz: 9097c8a42b63a8085858dea385b9a58017451aa019fa6562635cd960729e653dda42b33915ced46e0a5195bd653a243d37df26a6e02b47bb101cf015bb99c148
@@ -0,0 +1,67 @@
1
+ # all the cops that are enabled in the default
2
+ # https://github.com/bbatsov/rubocop/blob/master/config/enabled.yml
3
+ # https://github.com/bbatsov/rubocop/blob/master/config/default.yml
4
+
5
+ require: rubocop-performance
6
+ require: rubocop-rails
7
+
8
+ AllCops:
9
+ TargetRubyVersion: 2.6
10
+ Include:
11
+ - '**/Rakefile'
12
+ - '**/config.ru'
13
+ Exclude:
14
+ - 'db/**/*'
15
+ - 'config/**/*'
16
+ - 'script/**/*'
17
+ - !ruby/regexp /old_and_unused\.rb$/
18
+
19
+ Layout/LineLength:
20
+ Max: 160
21
+
22
+ Metrics/MethodLength:
23
+ CountComments: false # count full line comments?
24
+ Max: 12
25
+
26
+ Metrics/AbcSize:
27
+ Max: 20
28
+
29
+ Style/AndOr:
30
+ Enabled: false
31
+
32
+ Documentation:
33
+ Enabled: false
34
+
35
+ Style/ClassAndModuleChildren:
36
+ # Checks the style of children definitions at classes and modules.
37
+ #
38
+ # Basically there are two different styles:
39
+ #
40
+ # `nested` - have each child on a separate line
41
+ # class Foo
42
+ # class Bar
43
+ # end
44
+ # end
45
+ #
46
+ # `compact` - combine definitions as much as possible
47
+ # class Foo::Bar
48
+ # end
49
+ #
50
+ # The compact style is only forced, for classes / modules with one child.
51
+ EnforcedStyle: nested
52
+ SupportedStyles:
53
+ - nested
54
+ - compact
55
+ Enabled: false
56
+
57
+ CaseIndentation:
58
+ # Valid values are: case, end
59
+ EnforcedStyle: case
60
+ IndentOneStep: true
61
+
62
+ # Prefer `has_?` style for Hash methods
63
+ Style/PreferredHashMethods:
64
+ EnforcedStyle: verbose
65
+
66
+ Rails:
67
+ Enabled: true
data/Gemfile CHANGED
@@ -12,4 +12,5 @@ group :test do
12
12
  gem 'activerecord'
13
13
  gem 'pg'
14
14
  gem 'activesupport'
15
+ gem 'simplecov', require: false
15
16
  end
data/README.md CHANGED
@@ -3,6 +3,15 @@
3
3
  MidgetJobs is simple implementation of background jobs for [Ruby on Rails](https://rubyonrails.org). I does not meant to be used without it.
4
4
  It is connected to [ActiveJob](https://github.com/rails/rails/tree/master/activejob) and [PostgreSQL](https://www.postgresql.org) using its triggers, notifications and listening.
5
5
 
6
+ ## Update from 0.1.7 to 0.2.0
7
+ There is new column **runner** in **midget_jobs** table!
8
+ It is used to recognise who will run particular job (if there are multiple application over one database)
9
+
10
+ I added new configuration to Initializer. Add this to your config/initializers/midget_jobs.rb
11
+ ```Rails.application.config.x.midget_jobs.runner = Rails.application.class.parent_name```
12
+
13
+ Please create migration with generator
14
+ ```rails generate migration AddRunnerToMidgetJob runner:string:index```
6
15
 
7
16
  ## Installation
8
17
 
@@ -21,6 +30,24 @@ Then run
21
30
  $ rails generate midget_jobs:install
22
31
 
23
32
  This generator creates an initializer file at config/initializers and migrations to db/migrate
33
+
34
+ #### With Puma's multiple workers on production
35
+
36
+ In file `config/initializers/midget_jobs.rb` disable start with puma:
37
+
38
+ ...
39
+ if Rails.const_defined?('Server')# || $0.include?('puma')
40
+
41
+ In file `config/puma/production.rb` update `on_worker_boot do` block as:
42
+
43
+ ...
44
+ on_worker_boot do
45
+ ActiveRecord::Base.establish_connection if defined?(ActiveRecord)
46
+ Rails.logger.debug 'on_worker_boot starting jobs'
47
+
48
+ MidgetJobs.initialize_workers
49
+ ...
50
+ end
24
51
 
25
52
  ## Usage
26
53
 
@@ -5,9 +5,11 @@ class CreateMidgetJobs < ActiveRecord::Migration[6.0]
5
5
  t.string :queue
6
6
  t.jsonb :serialized
7
7
  t.datetime :run_at
8
+ t.string :runner
8
9
 
9
10
  t.timestamps
10
11
  end
11
12
  add_index :midget_jobs, :queue
13
+ add_index :midget_jobs, :runner
12
14
  end
13
15
  end
@@ -5,9 +5,11 @@ class CreateMidgetJobs < ActiveRecord::Migration[6.0]
5
5
  t.string :queue
6
6
  t.jsonb :serialized
7
7
  t.datetime :run_at
8
+ t.string :runner
8
9
 
9
10
  t.timestamps
10
11
  end
11
12
  add_index :midget_jobs, :queue
13
+ add_index :midget_jobs, :runner
12
14
  end
13
15
  end
@@ -1,5 +1,6 @@
1
1
  Rails.application.config.active_job.queue_adapter = :midget_job
2
2
  Rails.application.config.x.midget_jobs.at_once = 4
3
+ Rails.application.config.x.midget_jobs.runner = Rails.application.class.module_parent_name
3
4
 
4
5
  if Rails.const_defined?('Server') || $0.include?('puma')
5
6
  Rails.application.config.after_initialize do
@@ -1,3 +1,3 @@
1
1
  module MidgetJobs
2
- VERSION = "0.1.7"
2
+ VERSION = "0.2.5"
3
3
  end
@@ -1,24 +1,44 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module PostgresNotificationsListener
4
+ TIME_TO_DIE = 3
5
+ EXCEPTION_TIME = 0.333
6
+
4
7
  def listen_notifications
5
- Rails.logger.info "#{self.name} listening_job started"
8
+ Rails.logger.info "#{name} listening_job started"
6
9
  Thread.new do
7
- Rails.logger.info "#{self.name} listening_job running on #{self.name.pluralize.underscore}_notices"
8
- self.connection.execute "LISTEN #{self.name.pluralize.underscore}_notices"
10
+ Rails.logger.info "#{name} listening_job running on #{name.pluralize.underscore}_notices"
11
+ connection.execute "LISTEN #{name.pluralize.underscore}_notices"
9
12
  loop do
10
- begin
11
- Rails.logger.info "#{self.name} listening_job wait_for_notify"
12
- self.connection.raw_connection.wait_for_notify do |event, pid, payload|
13
- data = JSON.parse payload, symbolize_names: true
14
- Rails.logger.info "postgres #{event.inspect}, pid: #{pid.inspect}, data: #{data.inspect}"
15
- process_notification(data)
16
- end
17
- rescue StandardError => error
18
- Rails.logger.error "-------------Ex #{self.name} listening_job wait_for_notify #{error}----------------"
19
- retry
13
+ Rails.logger.info "#{name} listening_job wait_for_notify"
14
+ connection.raw_connection.wait_for_notify do |event, pid, payload|
15
+ data = JSON.parse payload, symbolize_names: true
16
+ Rails.logger.info "postgres #{event.inspect}, pid: #{pid.inspect}, data: #{data.inspect}"
17
+ process_notification(data)
20
18
  end
19
+ rescue PG::ConnectionBad => e
20
+ measure_exception_severity
21
+ Rails.logger.error "#{name} listening_job wait_for_notify lost connection #{e.inspect} retry #{exception_counter}th time!"
22
+ Rails.logger.error 'Reestablish AR connection...'
23
+ ActiveRecord::Base.connection.verify!
24
+ sleep 0.1
25
+ @exception_counter.to_i < EXCEPTION_TIME ? retry : raise(e)
26
+ rescue StandardError => e
27
+ measure_exception_severity
28
+ Rails.logger.error "#{name} listening_job wait_for_notify exception #{e.inspect} retry #{exception_counter}th time!"
29
+ sleep 0.1
30
+ @exception_counter.to_i < EXCEPTION_TIME ? retry : raise(e)
21
31
  end
22
32
  end.abort_on_exception = true
23
33
  end
34
+
35
+ private
36
+
37
+ def measure_exception_severity
38
+ @exception_counter, @last_exception_time = too_soon? ? [exception_counter.to_i + 1, @last_exception_time] : [0, Time.zone.now]
39
+ end
40
+
41
+ def too_soon?
42
+ (Time.zone.now - @last_exception_time) < TOO_SOON
43
+ end
24
44
  end
@@ -3,6 +3,8 @@ require 'models/concerns/postgres_notifications_listener'
3
3
  class MidgetJob < ActiveRecord::Base
4
4
  extend PostgresNotificationsListener
5
5
 
6
+ default_scope { where(runner: Rails.configuration.x.midget_jobs.runner) }
7
+
6
8
  scope :for_processing, -> { where('run_at < ?', Time.current) }
7
9
 
8
10
  validates :job_id, :queue, :serialized, :run_at, presence: true
@@ -29,6 +29,6 @@ Gem::Specification.new do |spec|
29
29
  spec.require_paths = ["lib"]
30
30
 
31
31
  spec.add_development_dependency "bundler", "~> 2.0"
32
- spec.add_development_dependency "rake", "~> 10.0"
32
+ spec.add_development_dependency "rake", ">= 12.3.3"
33
33
  spec.add_development_dependency "minitest", "~> 5.0"
34
34
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: midget_jobs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - josefchmel
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-12-19 00:00:00.000000000 Z
11
+ date: 2020-12-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -28,16 +28,16 @@ dependencies:
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: 12.3.3
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: 12.3.3
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: minitest
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -60,6 +60,7 @@ extensions: []
60
60
  extra_rdoc_files: []
61
61
  files:
62
62
  - ".gitignore"
63
+ - ".rubocop.yml"
63
64
  - ".travis.yml"
64
65
  - CODE_OF_CONDUCT.md
65
66
  - Gemfile