roqua-support 0.1.25 → 0.1.26

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
  SHA1:
3
- metadata.gz: c59df394193f13d45c71f26b935f59e890b98f96
4
- data.tar.gz: b0f6dc5880a4dfda1d96f554d5460dd180e6fc3b
3
+ metadata.gz: ecfd7d74378220979e7a8839f07ea9793a37265c
4
+ data.tar.gz: 8dfb4a419c0d3bc0222a2f743fcad30fc0e43141
5
5
  SHA512:
6
- metadata.gz: 0ccdada5a2cff7e753ae5e8d0278473a70d4e39b7c0f85f1287811946850f73612ade4bed1d5a081290cc6edde938a4190a32969cad62913e5e401e178a57f68
7
- data.tar.gz: 29ea857840bd5f40b59efd2b94eb599909cec72d2e9b58dcd16e71a210935ca9dd6344ad2dee79fda8772257db4edfa2276e9cd57745618d35c143b823474935
6
+ metadata.gz: d69f343ba3c51be195a532a892d8839eea4bea7cea5ee54f23e790f6fb56c2299c3aa1f94de49a1cad22f342c0feb78d5878d3a0bffed9be143d719224b7497f
7
+ data.tar.gz: 76a3f96b867e176bf948ea7bab491c1abd319b7eb02faf8dbb1f0aed73eb9c7251cef075ee5f51fca81b6383c35f1c05408aded3fda050bd339e77ddab60a668
data/.gitlab-ci.yml CHANGED
@@ -3,10 +3,6 @@ image: "registry.roqua.nl/roqua/roqua-build-images:ruby-2.3-rails-base-test"
3
3
  variables:
4
4
  RAILS_ENV: "test"
5
5
 
6
- stages:
7
- - test
8
- - publish
9
-
10
6
  cache:
11
7
  paths:
12
8
  - .gems
@@ -18,26 +14,13 @@ before_script:
18
14
  - bundle --jobs 2 --retry 3
19
15
 
20
16
  rails_41:
21
- stage: test
22
17
  script:
23
18
  - bundle exec appraisal rails41 bundle exec rspec
24
19
 
25
20
  rails_42:
26
- stage: test
27
21
  script:
28
22
  - bundle exec appraisal rails42 bundle exec rspec
29
23
 
30
24
  rails_50:
31
- stage: test
32
25
  script:
33
26
  - bundle exec appraisal rails50 bundle exec rspec
34
-
35
- build_and_publish_gem:
36
- stage: publish
37
- dependencies:
38
- - rails_41
39
- - rails_42
40
- - rails_50
41
- script:
42
- - gem build roqua-support.gemspec
43
- - gem push roqua-support-0.1.25.gem
data/Gemfile.lock CHANGED
@@ -8,7 +8,7 @@ GIT
8
8
  PATH
9
9
  remote: .
10
10
  specs:
11
- roqua-support (0.1.25)
11
+ roqua-support (0.1.26)
12
12
  active_interaction (~> 3.0)
13
13
  activesupport (>= 3.2, < 6)
14
14
  naught (~> 1.0)
@@ -33,6 +33,10 @@ GEM
33
33
  activemodel (>= 4, < 6)
34
34
  activemodel (5.0.1)
35
35
  activesupport (= 5.0.1)
36
+ activerecord (5.0.1)
37
+ activemodel (= 5.0.1)
38
+ activesupport (= 5.0.1)
39
+ arel (~> 7.0)
36
40
  activesupport (5.0.1)
37
41
  concurrent-ruby (~> 1.0, >= 1.0.2)
38
42
  i18n (~> 0.7)
@@ -44,6 +48,7 @@ GEM
44
48
  thor (>= 0.14.0)
45
49
  appsignal (2.3.1)
46
50
  rack
51
+ arel (7.1.4)
47
52
  ast (2.3.0)
48
53
  builder (3.2.3)
49
54
  coderay (1.1.1)
@@ -52,6 +57,11 @@ GEM
52
57
  railties (>= 3.0.0)
53
58
  thor (>= 0.14.6)
54
59
  concurrent-ruby (1.0.4)
60
+ delayed_job (4.1.4)
61
+ activesupport (>= 3.0, < 5.2)
62
+ delayed_job_active_record (4.1.2)
63
+ activerecord (>= 3.0, < 5.2)
64
+ delayed_job (>= 3.0, < 5)
55
65
  diff-lcs (1.3)
56
66
  erubis (2.7.0)
57
67
  ffi (1.9.17)
@@ -151,8 +161,10 @@ GEM
151
161
  ruby_dep (1.5.0)
152
162
  shellany (0.0.1)
153
163
  slop (3.6.0)
164
+ sqlite3 (1.3.13)
154
165
  thor (0.19.4)
155
166
  thread_safe (0.3.5)
167
+ timecop (0.9.1)
156
168
  tzinfo (1.2.2)
157
169
  thread_safe (~> 0.1)
158
170
  unicode-display_width (1.3.0)
@@ -167,14 +179,17 @@ DEPENDENCIES
167
179
  appsignal
168
180
  bundler (~> 1.0)
169
181
  combustion (~> 0.5.2)
182
+ delayed_job_active_record
170
183
  guard-rspec (~> 4.2.6)
171
- rake (~> 12.1)
184
+ rake
172
185
  responders
173
186
  roqua-support!
174
187
  roqua_styleguide!
175
188
  rspec (>= 2.12.0, < 4.0)
176
189
  rspec-instrumentation-matcher
177
190
  rspec-rails
191
+ sqlite3
192
+ timecop
178
193
 
179
194
  BUNDLED WITH
180
- 1.15.4
195
+ 1.16.1
data/README.md CHANGED
@@ -100,6 +100,16 @@ class ApiAreaController < ApplicationController
100
100
  ...
101
101
  ```
102
102
 
103
+ # AppSignal Probes
104
+
105
+ roqua-support contains one generic probe to monitor the current delayed job backlog count: `Roqua::Probes::DelayedJobProbe`
106
+
107
+ Enable it in a project by calling:
108
+
109
+ ```ruby
110
+ Roqua::Probes::DelayedJobProbe.enable
111
+ ```
112
+
103
113
  ### ActiveInteraction extensions
104
114
 
105
115
  ```
@@ -0,0 +1,11 @@
1
+ module Roqua
2
+ module Probes
3
+ module BaseProbe
4
+ def enable
5
+ new.tap do |probe|
6
+ Appsignal::Minutely.probes << probe unless Appsignal::Minutely.probes.map(&:class).include?(probe.class)
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ require_relative 'base_probe'
2
+
3
+ module Roqua
4
+ module Probes
5
+ class DelayedJobProbe
6
+ extend BaseProbe
7
+
8
+ def backlog_count
9
+ Delayed::Job.where(locked_at: nil).where('run_at < ?', Time.zone.now).count
10
+ end
11
+
12
+ def call
13
+ Appsignal.set_gauge('delayed_job_backlog_count', backlog_count)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -69,7 +69,7 @@ module Roqua
69
69
  end
70
70
 
71
71
  def notify_appsignal?(exception)
72
- const_defined?(:Appsignal) && !Appsignal.is_ignored_exception?(exception) && Appsignal.active?
72
+ const_defined?(:Appsignal) && Appsignal.active? && !Appsignal.is_ignored_exception?(exception)
73
73
  end
74
74
 
75
75
  def notify_appsignal(exception, labels, namespace)
@@ -1,5 +1,5 @@
1
1
  module Roqua
2
2
  module Support
3
- VERSION = '0.1.25'.freeze
3
+ VERSION = '0.1.26'.freeze
4
4
  end
5
5
  end
data/lib/roqua-support.rb CHANGED
@@ -2,6 +2,10 @@ require "roqua-support/version"
2
2
  require "roqua/support"
3
3
 
4
4
  module Roqua
5
+ module Probes
6
+ autoload :DelayedJobProbe, 'roqua/probes/delayed_job_probe'
7
+ end
8
+
5
9
  module Responders
6
10
  autoload :ApiErrorsResponder, 'roqua/responders/api_errors_responder'
7
11
  autoload :ActiveInteractionAwareResponder, 'roqua/responders/active_interaction_aware_responder'
@@ -23,7 +23,10 @@ Gem::Specification.new do |gem|
23
23
  gem.add_dependency 'active_interaction', '~> 3.0'
24
24
 
25
25
  gem.add_development_dependency 'bundler', '~> 1.0'
26
- gem.add_development_dependency 'rake', '~> 12.1'
26
+ gem.add_development_dependency 'rake'
27
27
  gem.add_development_dependency 'rspec', '>= 2.12.0', '< 4.0'
28
- gem.add_development_dependency 'appsignal', '~> 2.3', '>= 2.3.1'
28
+ gem.add_development_dependency 'appsignal', '>= 2.3.1'
29
+ gem.add_development_dependency 'delayed_job_active_record'
30
+ gem.add_development_dependency 'sqlite3'
31
+ gem.add_development_dependency 'timecop'
29
32
  end
@@ -1,17 +1,6 @@
1
- require 'roqua/core_ext/activerecord/uniq_find_or_create'
1
+ require 'spec_helper'
2
2
 
3
- module ActiveRecord
4
- class Base
5
- def self.find_by(attributes)
6
- end
7
- end
8
-
9
- class RecordNotUnique < StandardError
10
- end
11
-
12
- class RecordInvalid < StandardError
13
- end
14
- end
3
+ require 'roqua/core_ext/activerecord/uniq_find_or_create'
15
4
 
16
5
  describe ActiveRecord::Base do
17
6
  let(:attributes) { double('attributes') }
@@ -32,14 +21,14 @@ describe ActiveRecord::Base do
32
21
  it 'returns a concurrenlty created record' do
33
22
  allow(ActiveRecord::Base).to receive(:find_by).with(attributes).and_return record
34
23
  allow(ActiveRecord::Base).to receive(:find_or_create_by).with(attributes, &block)
35
- .and_raise ActiveRecord::RecordNotUnique
24
+ .and_raise ActiveRecord::RecordNotUnique.new('')
36
25
  expect(ActiveRecord::Base.uniq_find_or_create_by attributes, &block).to eq(record)
37
26
  end
38
27
 
39
28
  it 'raises when a concurrent record is detected by the database but could not be queried for unknown reasons' do
40
29
  allow(ActiveRecord::Base).to receive(:find_by).with(attributes).and_return nil
41
30
  allow(ActiveRecord::Base).to receive(:find_or_create_by).with(attributes, &block)
42
- .and_raise ActiveRecord::RecordNotUnique
31
+ .and_raise ActiveRecord::RecordNotUnique.new('')
43
32
  expect do
44
33
  ActiveRecord::Base.uniq_find_or_create_by attributes, &block
45
34
  end.to raise_error ActiveRecord::RecordNotUnique
@@ -66,21 +55,21 @@ describe ActiveRecord::Base do
66
55
  it 'returns a concurrenlty created record' do
67
56
  allow(ActiveRecord::Base).to receive(:find_by).with(attributes).and_return record
68
57
  allow(ActiveRecord::Base).to receive(:find_or_create_by!).with(attributes, &block)
69
- .and_raise ActiveRecord::RecordNotUnique
58
+ .and_raise ActiveRecord::RecordNotUnique.new('')
70
59
  expect(ActiveRecord::Base.uniq_find_or_create_by! attributes, &block).to eq(record)
71
60
  end
72
61
 
73
62
  it 'raises when a concurrent record is detected by the database but could not be queried for unknown reasons' do
74
63
  allow(ActiveRecord::Base).to receive(:find_by).with(attributes).and_return nil
75
64
  allow(ActiveRecord::Base).to receive(:find_or_create_by!).with(attributes, &block)
76
- .and_raise ActiveRecord::RecordNotUnique
65
+ .and_raise ActiveRecord::RecordNotUnique.new('')
77
66
  expect do
78
67
  ActiveRecord::Base.uniq_find_or_create_by! attributes, &block
79
68
  end.to raise_error ActiveRecord::RecordNotUnique
80
69
  end
81
70
 
82
71
  it 'raises when creating a new record causes validation failures not due to concurrency' do
83
- exception = ActiveRecord::RecordInvalid.new 'some_validation_error'
72
+ exception = StandardError.new('some_validation_error')
84
73
  allow(ActiveRecord::Base).to receive(:find_or_create_by!).with(attributes, &block).and_raise exception
85
74
  expect { ActiveRecord::Base.uniq_find_or_create_by! attributes, &block }.to raise_error(exception)
86
75
  end
@@ -0,0 +1,51 @@
1
+ require 'spec_helper'
2
+ require 'delayed_job_active_record'
3
+ require 'timecop'
4
+
5
+ require 'roqua/probes/delayed_job_probe'
6
+
7
+ describe Roqua::Probes::DelayedJobProbe do
8
+ before { Timecop.freeze }
9
+ after { Timecop.return }
10
+ subject(:probe) { Roqua::Probes::DelayedJobProbe.new }
11
+
12
+ describe 'backlog_count' do
13
+ context 'if a single job unlocked job exists that has a run_at in the past' do
14
+ def create_jobs
15
+ Delayed::Job.create!(run_at: 1.second.ago)
16
+ 2.times { Delayed::Job.create!(run_at: 1.second.ago, locked_at: Time.zone.now) }
17
+ Delayed::Job.create!(run_at: Time.zone.now)
18
+ Delayed::Job.create!(run_at: 1.second.from_now)
19
+ end
20
+
21
+ it 'returns 1' do
22
+ expect { create_jobs }.to change { probe.backlog_count }.from(0).to(1)
23
+ end
24
+ end
25
+ end
26
+
27
+ describe 'call' do
28
+ it 'sends the correct metric to Appsignal' do
29
+ expect(probe).to receive(:backlog_count).and_return(12)
30
+ expect(Appsignal).to receive(:set_gauge).with('delayed_job_backlog_count', 12)
31
+ probe.call
32
+ end
33
+ end
34
+
35
+ context '.enable' do
36
+ before { Appsignal::Minutely.probes.clear }
37
+ after { Appsignal::Minutely.probes.clear }
38
+
39
+ it 'adds our custom probes to Appsignal' do
40
+ expect { Roqua::Probes::DelayedJobProbe.enable }
41
+ .to change { Appsignal::Minutely.probes.count }.by(1)
42
+
43
+ expect(Appsignal::Minutely.probes.map(&:class)).to include(Roqua::Probes::DelayedJobProbe)
44
+ end
45
+
46
+ it 'will not add the same probe twice if called multiple times' do
47
+ expect { 2.times { Roqua::Probes::DelayedJobProbe.enable } }
48
+ .to change { Appsignal::Minutely.probes.count }.by(1)
49
+ end
50
+ end
51
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,5 @@
1
+ ENV['RAILS_ENV'] = 'test'
2
+
1
3
  require 'rubygems'
2
4
  require 'bundler/setup'
3
5
 
@@ -7,3 +9,29 @@ Combustion.initialize! :action_controller
7
9
 
8
10
  require 'appsignal'
9
11
  require 'rspec/rails'
12
+
13
+ require 'delayed_job_active_record'
14
+
15
+ Delayed::Worker.logger = Logger.new(Tempfile.new('roqua-support-delayed-job.log'))
16
+
17
+ ActiveRecord::Base.establish_connection :adapter => 'sqlite3', :database => ':memory:'
18
+ ActiveRecord::Base.logger = Delayed::Worker.logger
19
+ ActiveRecord::Migration.verbose = false
20
+
21
+ ActiveRecord::Schema.define do
22
+ create_table :delayed_jobs, :force => true do |t|
23
+ t.integer :priority, :default => 0
24
+ t.integer :attempts, :default => 0
25
+ t.text :handler
26
+ t.text :last_error
27
+ t.datetime :run_at
28
+ t.datetime :locked_at
29
+ t.datetime :failed_at
30
+ t.string :locked_by
31
+ t.string :queue
32
+ t.string :cron
33
+ t.timestamps null: false
34
+ end
35
+
36
+ add_index :delayed_jobs, [:priority, :run_at], :name => 'delayed_jobs_priority'
37
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roqua-support
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.25
4
+ version: 0.1.26
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marten Veldthuis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-11-08 00:00:00.000000000 Z
11
+ date: 2018-03-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -76,16 +76,16 @@ dependencies:
76
76
  name: rake
77
77
  requirement: !ruby/object:Gem::Requirement
78
78
  requirements:
79
- - - "~>"
79
+ - - ">="
80
80
  - !ruby/object:Gem::Version
81
- version: '12.1'
81
+ version: '0'
82
82
  type: :development
83
83
  prerelease: false
84
84
  version_requirements: !ruby/object:Gem::Requirement
85
85
  requirements:
86
- - - "~>"
86
+ - - ">="
87
87
  - !ruby/object:Gem::Version
88
- version: '12.1'
88
+ version: '0'
89
89
  - !ruby/object:Gem::Dependency
90
90
  name: rspec
91
91
  requirement: !ruby/object:Gem::Requirement
@@ -110,22 +110,58 @@ dependencies:
110
110
  name: appsignal
111
111
  requirement: !ruby/object:Gem::Requirement
112
112
  requirements:
113
- - - "~>"
113
+ - - ">="
114
114
  - !ruby/object:Gem::Version
115
- version: '2.3'
115
+ version: 2.3.1
116
+ type: :development
117
+ prerelease: false
118
+ version_requirements: !ruby/object:Gem::Requirement
119
+ requirements:
116
120
  - - ">="
117
121
  - !ruby/object:Gem::Version
118
122
  version: 2.3.1
123
+ - !ruby/object:Gem::Dependency
124
+ name: delayed_job_active_record
125
+ requirement: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - ">="
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
119
130
  type: :development
120
131
  prerelease: false
121
132
  version_requirements: !ruby/object:Gem::Requirement
122
133
  requirements:
123
- - - "~>"
134
+ - - ">="
124
135
  - !ruby/object:Gem::Version
125
- version: '2.3'
136
+ version: '0'
137
+ - !ruby/object:Gem::Dependency
138
+ name: sqlite3
139
+ requirement: !ruby/object:Gem::Requirement
140
+ requirements:
126
141
  - - ">="
127
142
  - !ruby/object:Gem::Version
128
- version: 2.3.1
143
+ version: '0'
144
+ type: :development
145
+ prerelease: false
146
+ version_requirements: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ - !ruby/object:Gem::Dependency
152
+ name: timecop
153
+ requirement: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - ">="
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ type: :development
159
+ prerelease: false
160
+ version_requirements: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ version: '0'
129
165
  description: 'Logging backend, freedom patches, '
130
166
  email: marten@roqua.nl
131
167
  executables: []
@@ -159,6 +195,8 @@ files:
159
195
  - lib/roqua/core_ext/enumerable/sort_by_alphanum.rb
160
196
  - lib/roqua/core_ext/fabrication/singleton.rb
161
197
  - lib/roqua/core_ext/fixnum/clamp.rb
198
+ - lib/roqua/probes/base_probe.rb
199
+ - lib/roqua/probes/delayed_job_probe.rb
162
200
  - lib/roqua/responders/active_interaction_aware_responder.rb
163
201
  - lib/roqua/responders/api_errors_responder.rb
164
202
  - lib/roqua/support.rb
@@ -179,6 +217,7 @@ files:
179
217
  - spec/roqua/core_ext/enumerable/sort_by_alphanum_spec.rb
180
218
  - spec/roqua/core_ext/fabrication/singleton_spec.rb
181
219
  - spec/roqua/core_ext/fixnum/clamp_spec.rb
220
+ - spec/roqua/probes/delayed_job_probe_spec.rb
182
221
  - spec/roqua/responders/active_interaction_aware_responder_spec.rb
183
222
  - spec/roqua/responders/api_errors_responder_spec.rb
184
223
  - spec/roqua/support/errors_spec.rb
@@ -210,7 +249,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
210
249
  version: '0'
211
250
  requirements: []
212
251
  rubyforge_project:
213
- rubygems_version: 2.5.2
252
+ rubygems_version: 2.5.2.2
214
253
  signing_key:
215
254
  specification_version: 4
216
255
  summary: Helper objects and proxies used by a lot of RoQua applications
@@ -223,6 +262,7 @@ test_files:
223
262
  - spec/roqua/core_ext/enumerable/sort_by_alphanum_spec.rb
224
263
  - spec/roqua/core_ext/fabrication/singleton_spec.rb
225
264
  - spec/roqua/core_ext/fixnum/clamp_spec.rb
265
+ - spec/roqua/probes/delayed_job_probe_spec.rb
226
266
  - spec/roqua/responders/active_interaction_aware_responder_spec.rb
227
267
  - spec/roqua/responders/api_errors_responder_spec.rb
228
268
  - spec/roqua/support/errors_spec.rb