checker_jobs 0.1.2.pre → 1.0.0

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
- SHA1:
3
- metadata.gz: bd7238a9e052db0d3953584be6cf3d082ae6b171
4
- data.tar.gz: a4bf0b5505b76cbc4c23b195bdb9af6bc14c8f7d
2
+ SHA256:
3
+ metadata.gz: dff9e8e2b91b729928d02a856b2a1848afe909ed2c17a5ba39cded6f992e8087
4
+ data.tar.gz: 11ae8c80cb23614057e45fbdb70de548cb7dac6e9e3368564a586a0d247272e9
5
5
  SHA512:
6
- metadata.gz: fb9d91c1b2eacb5f86cc4304fdaf4bb7bee7f5addb90094e7f81df44fab5795f211f3e7891e654522313fd875ed0546951cd39cc0d2904ccf6f88c80113dcade
7
- data.tar.gz: '0586d068670200ddf86e62f848bf5ed636992eb4b6de358653183b8cad61e3c519ce31c741933c43077d9839fdf3bc98e7aa736fc02690293ec06a98cb335a8e'
6
+ metadata.gz: bf7ed95487af7d2d5df3a8c884d17a66fa90fef168a7c7c72b6551a595ae12c46765024117e54b02e821aadc0d1b0c79a566ff45472a4dc97181b7b503f0f0c4
7
+ data.tar.gz: 6754adfa0d2849ee8cabecd9e379489908f85d2a6bf349dbba75d3513645a0269f8f7e5848d375a4854b5fd93cd3b50c05c5e137d93a470099f9b4dd6a1dd02c
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- checker_jobs (0.1.2.pre)
4
+ checker_jobs (1.0.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
@@ -41,7 +41,7 @@ GEM
41
41
  coderay (1.1.2)
42
42
  concurrent-ruby (1.0.5)
43
43
  connection_pool (2.2.1)
44
- crass (1.0.3)
44
+ crass (1.0.4)
45
45
  daemons (1.2.6)
46
46
  diff-lcs (1.3)
47
47
  docile (1.1.5)
@@ -109,16 +109,16 @@ GEM
109
109
  byebug (~> 9.1)
110
110
  pry (~> 0.10)
111
111
  public_suffix (3.0.1)
112
- rack (2.0.4)
113
- rack-protection (2.0.1)
112
+ rack (2.0.5)
113
+ rack-protection (2.0.3)
114
114
  rack
115
115
  rack-test (0.8.2)
116
116
  rack (>= 1.0, < 3)
117
117
  rails-dom-testing (2.0.3)
118
118
  activesupport (>= 4.2.0)
119
119
  nokogiri (>= 1.6)
120
- rails-html-sanitizer (1.0.3)
121
- loofah (~> 2.0)
120
+ rails-html-sanitizer (1.0.4)
121
+ loofah (~> 2.2, >= 2.2.2)
122
122
  rainbow (2.2.2)
123
123
  rake
124
124
  rake (10.5.0)
@@ -160,10 +160,10 @@ GEM
160
160
  json (>= 1.8, < 3)
161
161
  simplecov-html (~> 0.10.0)
162
162
  simplecov-html (0.10.2)
163
- sinatra (2.0.1)
163
+ sinatra (2.0.3)
164
164
  mustermann (~> 1.0)
165
165
  rack (~> 2.0)
166
- rack-protection (= 2.0.1)
166
+ rack-protection (= 2.0.3)
167
167
  tilt (~> 2.0)
168
168
  skinny (0.2.2)
169
169
  eventmachine (~> 1.0)
data/README.md CHANGED
@@ -41,7 +41,7 @@ class UsersChecker
41
41
 
42
42
  options sidekiq: { queue: :slow }
43
43
 
44
- notify "oss@drivy.com"
44
+ notify :email, to: "oss@drivy.com"
45
45
 
46
46
  ensure_no :negative_rental_credit do
47
47
  # The following code is an over-simplification
@@ -74,26 +74,30 @@ gem 'checker_jobs'
74
74
 
75
75
  ## Usage
76
76
 
77
- Have a look at the `examples` directory of the repository to get a clearer idea
78
- about how to use and the gem is offering.
77
+ Have a look at the examples directory of the repository to get a clearer idea about how to use and the gem is offering.
79
78
 
80
79
  ### Configure
81
80
 
82
- At the moment this gems supports [Drivy][gh-drivy]'s stack which includes
83
- [Sidekiq][gh-sidekiq] and [Rails][rails]. It has been designed to supports more
84
- than Sidekiq a job processor and more that ActionMailer as a notification
85
- gateway. If you're on the same stack as we are, configuration looks like this:
86
-
87
81
  ``` ruby
88
82
  require "checker_jobs"
89
83
 
90
- CheckerJobs.configure do |config|
91
- config.repository_url = { github: "drivy/checker_jobs" }
84
+ CheckerJobs.configure do |c|
85
+ c.jobs_processor = :sidekiq
86
+
87
+ c.notifier :email do |options|
88
+ options[:formatter_class] = CheckerJobs::Notifiers::EmailDefaultFormatter
89
+ options[:email_options] = {
90
+ from: "oss@drivy.com",
91
+ reply_to: "no-reply@drivy.com",
92
+ }
93
+ end
92
94
 
93
- config.jobs_processor = :sidekiq
95
+ c.notifier :logger do |options|
96
+ options[:logdev] = STDOUT
97
+ options[:level] = Logger::INFO
98
+ end
94
99
 
95
- config.emails_backend = :action_mailer
96
- config.emails_options = { from: "oss@drivy.com", reply_to: "no-reply@drivy.com" }
100
+ c.repository_url = { github: "drivy/checker_jobs" }
97
101
  end
98
102
 
99
103
  ```
@@ -105,6 +109,21 @@ are already configured.
105
109
  If you're on a different stack and you'll like to add a new job processor or
106
110
  notification backend in this gem, [drop us a line][d-jobs].
107
111
 
112
+ ### Job Processor
113
+
114
+ At the moment, only [Sidekiq][gh-sidekiq] is supported as a job processor to asynchronously check for data inconsitencies.
115
+ The gem is designed to supports more processor.
116
+ PRs are appreciated 🙏
117
+
118
+ ### Notifiers
119
+
120
+ We support different kind of notifiers, as of today we have the following:
121
+
122
+ - `:email`: uses `ActionMailer` to send emails. You can pass it any `ActionMailer` options.
123
+ - `:logger`: Uses `Logger` to output inconsitencies in the log. Takes the following params:
124
+ - `logdev`: The log device. This is a filename (String) or IO object (typically STDOUT, STDERR, or an open file).
125
+ - `level`: Logging severity threshold (e.g. Logger::INFO)
126
+
108
127
  ### Write checkers
109
128
 
110
129
  A checker is a class that inherits `CheckerJobs::Base` and uses the
@@ -116,7 +135,7 @@ class UserChecker
116
135
 
117
136
  options sidekiq: { queue: :fast }
118
137
 
119
- notify "tech@drivy.com"
138
+ notify :email, to: "oss@drivy.com"
120
139
 
121
140
  ensure_no :user_without_email do
122
141
  UserRepository.missing_email.size
@@ -128,7 +147,7 @@ The `UserChecker` will have the same interface as your usual jobs. In this
128
147
  example, `UserChecker` will be a `Sidekiq::Worker`. Its `#perform` method will
129
148
  run the check named `:user_without_email` and if
130
149
  `UserRepository.missing_email.size` is greater than 0 then an email will be
131
- fired through ActionMailer to `tech@drivy.com`.
150
+ fired through ActionMailer to `oss@drivy.com`.
132
151
 
133
152
  ### Schedule checks
134
153
 
@@ -150,10 +169,3 @@ You'll find out that the CI is setup to run test coverage and linting.
150
169
  ## License
151
170
 
152
171
  The gem is available as open source under the terms of the [MIT License][licence].
153
-
154
-
155
- [d-jobs]: https://www.drivy.com/jobs
156
- [gh-drivy]: https://github.com/drivy
157
- [gh-sidekiq]: https://github.com/mperham/sidekiq
158
- [licence]: http://opensource.org/licenses/MIT
159
- [rails]: http://rubyonrails.org
data/checker_jobs.gemspec CHANGED
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
8
8
  spec.authors = ["Drivy", "Nicolas Zermati"]
9
9
  spec.email = ["oss@drivy.com"]
10
10
 
11
- spec.summary = "Asynchronous data consistency checks"
11
+ spec.summary = "Regression tests for data"
12
12
  spec.description = ""
13
13
  spec.homepage = "https://github.com/drivy/checker_jobs"
14
14
  spec.license = "MIT"
@@ -21,8 +21,13 @@ CheckerJobs.configure do |config|
21
21
 
22
22
  config.jobs_processor = :sidekiq
23
23
 
24
- config.emails_backend = :action_mailer
25
- config.emails_options = { from: "oss@drivy.com", reply_to: "no-reply@drivy.com" }
24
+ config.notifier :email do |options|
25
+ options[:formatter_class] = CheckerJobs::Notifiers::EmailDefaultFormatter
26
+ options[:email_options] = {
27
+ from: "oss@drivy.com",
28
+ reply_to: "no-reply@drivy.com",
29
+ }
30
+ end
26
31
 
27
32
  config.around_check = -> {
28
33
  puts "Starting check #{check.name}..."
@@ -40,7 +45,7 @@ class UserChecker
40
45
 
41
46
  options sidekiq: { queue: :fast }
42
47
 
43
- notify "tech@drivy.com"
48
+ notify :email, to: "tech@drivy.com"
44
49
 
45
50
  ensure_no :inconsistent_payment do
46
51
  UserRepository.missing_email.size
@@ -10,9 +10,8 @@ CheckerJobs::Checks::Base = Struct.new(:klass, :name, :options, :block) do
10
10
  private
11
11
 
12
12
  def notify(count:, entries: nil)
13
- CheckerJobs.configuration.emails_backend_class.
14
- new(self, count, entries).
15
- notify
13
+ notifier_class = CheckerJobs.configuration.notifier_class(klass.notifier)
14
+ notifier_class.new(self, count, entries).notify
16
15
  end
17
16
 
18
17
  def handle_result(_result)
@@ -4,23 +4,31 @@ require "checker_jobs/jobs_processors"
4
4
  class CheckerJobs::Configuration
5
5
  DEFAULT_TIME_BETWEEN_CHECKS = 15 * 60 # 15 minutes, expressed in seconds
6
6
 
7
+ NOTIFIER_CLASSES = {
8
+ email: "CheckerJobs::Notifiers::Email",
9
+ logger: "CheckerJobs::Notifiers::Logger",
10
+ }.freeze
11
+
7
12
  attr_accessor :jobs_processor,
8
- :emails_backend,
9
- :emails_options,
10
- :emails_formatter_class,
13
+ :notifiers_options,
11
14
  :time_between_checks,
12
15
  :repository_url,
13
16
  :around_check
14
17
 
15
18
  def self.default
16
19
  new.tap do |config|
17
- config.emails_options = {}
18
- config.emails_formatter_class = CheckerJobs::EmailsBackends::DefaultFormatter
20
+ config.notifiers_options = {}
19
21
  config.time_between_checks = DEFAULT_TIME_BETWEEN_CHECKS
20
22
  config.around_check = ->(&block) { block.call }
21
23
  end
22
24
  end
23
25
 
26
+ def notifier(notifier_symbol)
27
+ options = {}
28
+ yield(options)
29
+ @notifiers_options[notifier_symbol] = options
30
+ end
31
+
24
32
  def jobs_processor_module
25
33
  case jobs_processor
26
34
  when :sidekiq
@@ -30,12 +38,10 @@ class CheckerJobs::Configuration
30
38
  end
31
39
  end
32
40
 
33
- def emails_backend_class
34
- case emails_backend
35
- when :action_mailer
36
- CheckerJobs::EmailsBackends::ActionMailer
37
- else
38
- raise CheckerJobs::UnsupportedConfigurationOption.new(:emails_backend, emails_backend)
41
+ def notifier_class(notifier)
42
+ notifier_class_name = NOTIFIER_CLASSES.fetch(notifier) do
43
+ raise CheckerJobs::UnsupportedConfigurationOption.new(:notifier, notifier)
39
44
  end
45
+ Object.const_get(notifier_class_name)
40
46
  end
41
47
  end
@@ -16,8 +16,9 @@ module CheckerJobs::DSL
16
16
  @options = options_hash
17
17
  end
18
18
 
19
- def notify(target)
20
- @notification_target = target
19
+ def notify(notifier, notifier_options = {})
20
+ @notifier = notifier
21
+ @notifier_options = notifier_options
21
22
  end
22
23
 
23
24
  def interval(duration)
@@ -40,10 +41,14 @@ module CheckerJobs::DSL
40
41
  # Private API
41
42
  #
42
43
 
43
- def notification_target
44
- raise CheckerJobs::MissingNotificationTarget, self.class unless defined?(@notification_target)
44
+ def notifier
45
+ raise CheckerJobs::MissingNotifier, self.class unless defined?(@notifier)
46
+ @notifier
47
+ end
45
48
 
46
- @notification_target
49
+ def notifier_options
50
+ raise CheckerJobs::MissingNotifier, self.class unless defined?(@notifier)
51
+ @notifier_options
47
52
  end
48
53
 
49
54
  def time_between_checks
@@ -1,4 +1,5 @@
1
- module CheckerJobs::EmailsBackends
2
- autoload :ActionMailer, "checker_jobs/emails_backends/action_mailer"
3
- autoload :DefaultFormatter, "checker_jobs/emails_backends/default_formatter"
1
+ module CheckerJobs::Notifiers
2
+ autoload :Email, "checker_jobs/notifiers/email"
3
+ autoload :EmailDefaultFormatter, "checker_jobs/notifiers/email_default_formatter"
4
+ autoload :Logger, "checker_jobs/notifiers/logger"
4
5
  end
@@ -2,7 +2,10 @@ module CheckerJobs
2
2
  class Error < StandardError
3
3
  end
4
4
 
5
- class MissingNotificationTarget < Error
5
+ class MissingNotifier < Error
6
+ end
7
+
8
+ class InvalidNotifierOptions < Error
6
9
  end
7
10
 
8
11
  class Unconfigured < Error
@@ -1,9 +1,12 @@
1
1
  require "action_mailer"
2
2
 
3
- class CheckerJobs::EmailsBackends::ActionMailer
3
+ class CheckerJobs::Notifiers::Email
4
4
  def initialize(check, count, entries)
5
5
  @check = check
6
6
  @formatter = formatter_class.new(check, count, entries)
7
+ @defaults = { subject: @formatter.subject }
8
+
9
+ raise CheckerJobs::InvalidNotifierOptions unless valid?
7
10
  end
8
11
 
9
12
  def notify
@@ -12,15 +15,22 @@ class CheckerJobs::EmailsBackends::ActionMailer
12
15
 
13
16
  private
14
17
 
18
+ def valid?
19
+ options[:to].is_a?(String)
20
+ end
21
+
15
22
  def options
16
- CheckerJobs.configuration.emails_options.merge({
17
- to: @check.klass.notification_target,
18
- subject: @formatter.subject,
19
- })
23
+ @options ||= @defaults.
24
+ merge(notifier_options[:email_options]).
25
+ merge(@check.klass.notifier_options)
20
26
  end
21
27
 
22
28
  def formatter_class
23
- CheckerJobs.configuration.emails_formatter_class
29
+ notifier_options[:formatter_class] || CheckerJobs::Notifiers::EmailDefaultFormatter
30
+ end
31
+
32
+ def notifier_options
33
+ CheckerJobs.configuration.notifiers_options[@check.klass.notifier]
24
34
  end
25
35
 
26
36
  # Simple mailer class based on ActionMailer to send HTML emails while reusing
@@ -1,4 +1,4 @@
1
- class CheckerJobs::EmailsBackends::DefaultFormatter
1
+ class CheckerJobs::Notifiers::EmailDefaultFormatter
2
2
  def initialize(check, count, entries)
3
3
  @check = check
4
4
  @count = count
@@ -0,0 +1,51 @@
1
+ require "logger"
2
+
3
+ class CheckerJobs::Notifiers::Logger
4
+ DEFAULT_LEVEL = Logger::INFO
5
+ DEFAULT_LOGDEV = STDOUT
6
+
7
+ def initialize(check, count, entries)
8
+ @check = check
9
+ @count = count
10
+ @entries = entries
11
+ raise CheckerJobs::InvalidNotifierOptions unless valid?
12
+
13
+ @logger = Logger.new(logdev)
14
+ @logger.level = level
15
+ end
16
+
17
+ def notify
18
+ @logger.add(level, format, @check.name.tr("_", " ").capitalize)
19
+ end
20
+
21
+ # override this
22
+ def format
23
+ "found #{@count} entries"
24
+ end
25
+
26
+ private
27
+
28
+ def valid?
29
+ (logdev.is_a?(String) || logdev.is_a?(IO)) &&
30
+ [
31
+ Logger::UNKNOWN, Logger::FATAL, Logger::ERROR,
32
+ Logger::WARN, Logger::INFO, Logger::DEBUG
33
+ ].include?(level)
34
+ end
35
+
36
+ def level
37
+ @level ||= @check.klass.notifier_options[:level] ||
38
+ notifier_options[:level] ||
39
+ DEFAULT_LEVEL
40
+ end
41
+
42
+ def logdev
43
+ @logdev ||= @check.klass.notifier_options[:logdev] ||
44
+ notifier_options[:logdev] ||
45
+ DEFAULT_LOGDEV
46
+ end
47
+
48
+ def notifier_options
49
+ CheckerJobs.configuration.notifiers_options[@check.klass.notifier]
50
+ end
51
+ end
@@ -1,3 +1,3 @@
1
1
  module CheckerJobs
2
- VERSION = "0.1.2.pre".freeze
2
+ VERSION = "1.0.0".freeze
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: checker_jobs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2.pre
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Drivy
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2018-04-03 00:00:00.000000000 Z
12
+ date: 2018-07-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: actionmailer
@@ -210,11 +210,12 @@ files:
210
210
  - lib/checker_jobs/configuration.rb
211
211
  - lib/checker_jobs/dsl.rb
212
212
  - lib/checker_jobs/emails_backends.rb
213
- - lib/checker_jobs/emails_backends/action_mailer.rb
214
- - lib/checker_jobs/emails_backends/default_formatter.rb
215
213
  - lib/checker_jobs/errors.rb
216
214
  - lib/checker_jobs/jobs_processors.rb
217
215
  - lib/checker_jobs/jobs_processors/sidekiq.rb
216
+ - lib/checker_jobs/notifiers/email.rb
217
+ - lib/checker_jobs/notifiers/email_default_formatter.rb
218
+ - lib/checker_jobs/notifiers/logger.rb
218
219
  - lib/checker_jobs/version.rb
219
220
  homepage: https://github.com/drivy/checker_jobs
220
221
  licenses:
@@ -231,13 +232,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
231
232
  version: '0'
232
233
  required_rubygems_version: !ruby/object:Gem::Requirement
233
234
  requirements:
234
- - - ">"
235
+ - - ">="
235
236
  - !ruby/object:Gem::Version
236
- version: 1.3.1
237
+ version: '0'
237
238
  requirements: []
238
239
  rubyforge_project:
239
- rubygems_version: 2.6.14
240
+ rubygems_version: 2.7.6
240
241
  signing_key:
241
242
  specification_version: 4
242
- summary: Asynchronous data consistency checks
243
+ summary: Regression tests for data
243
244
  test_files: []