qmin 0.0.7 → 0.0.8

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
  SHA1:
3
- metadata.gz: 69e96cc20325d7b8809946ac027cbb9de06c7112
4
- data.tar.gz: 59e9483bfa81502f4346e2d1e4f09a7a21121b58
3
+ metadata.gz: 224035ccd522282d02bb6c6020a115ffe5353d14
4
+ data.tar.gz: 9c0f5ac6458d44113c9ecf656c3b5e82120510bc
5
5
  SHA512:
6
- metadata.gz: 565eb2604a080306eb7e729213a9f2b4f6b554787eeeae3cf6efc631407bd21efe4f9cbb463f78c45c844ea6c72287833edb287aaa319ff34e108277172cd0d9
7
- data.tar.gz: e486391dd19b23339113ef26ef0ccb660e85db02578f74bb6286f89191ea5b45d72d57c2f44193870b0a5092d6cda9fd10b04db32e1c02402a6adf5c574e769f
6
+ metadata.gz: 597fbd9165320d0183e3c7bb523722bdec58f6ccb9fbb189dbc816706f34ae6de13be56c2e499fdc10dbe0b2f531255ae83505d0e4ddf06a64386165a94277e0
7
+ data.tar.gz: 2797a8f514bd41aefb36dda45a50a86a8c13a1dcd89a8d4c9ac04ee1d450c36d96de19536539e2a95f6743f3facfc1814b411f5295e0ebb89e5e88881d6626b8
@@ -4,14 +4,20 @@ require 'qmin/core_ext/string'
4
4
  require 'qmin/strategy/inline'
5
5
  require 'qmin/strategy/noop'
6
6
 
7
+ require 'qmin/reporting/inline'
8
+ require 'qmin/reporting/noop'
9
+
7
10
  if defined? Resque
8
11
  require 'qmin/resque/background_call_job'
9
12
  require 'qmin/resque/base_job'
10
13
  require 'qmin/strategy/resque'
11
14
  end
12
15
 
16
+ if defined? Mail
17
+ require 'qmin/reporting/mail'
18
+ end
19
+
13
20
  module Qmin
14
- MustDefineStrategyError = Class.new(StandardError)
15
21
 
16
22
  protected
17
23
 
@@ -8,7 +8,7 @@ class String
8
8
  downcase
9
9
  end unless String.respond_to?(:underscore)
10
10
 
11
- # shamelessly stolen from resque
11
+ # copied from resque
12
12
  def constantize
13
13
  names = self.split('::')
14
14
  names.shift if names.empty? || names.first.empty?
@@ -1,30 +1,43 @@
1
1
  module Qmin
2
2
  # Handles configuration and dispatches method calls to configured strategy
3
3
  class Qmin
4
- # configure default strategy
5
- def self.default_strategy=(strategy)
6
- @@default_strategy = strategy
7
- end
8
4
 
9
- def self.current
10
- @@current ||= new
11
- end
5
+ class << self
6
+ def default_reporter=(reporter)
7
+ @default_reporter = reporter
8
+ @current = nil # reset current, so the newly set reporter is used
9
+ end
12
10
 
13
- def self.enqueue(worker_class, *args)
14
- current.enqueue worker_class, *args
15
- end
11
+ def default_reporter
12
+ @default_reporter || Reporting::Inline
13
+ end
16
14
 
17
- def self.background_call(instance, method_name)
18
- current.background_call(instance, method_name)
19
- end
15
+ # configure default strategy
16
+ def default_strategy=(strategy)
17
+ @default_strategy = strategy
18
+ @current = nil # reset current, so the newly set strategy is used
19
+ end
20
+
21
+ def default_strategy
22
+ @default_strategy || Strategy::Inline
23
+ end
20
24
 
21
- def initialize(strategy = nil)
22
- begin
23
- @strategy = (strategy || @@default_strategy).new
24
- rescue NameError
25
- raise MustDefineStrategyError.new
25
+ def current
26
+ @current ||= new
27
+ end
28
+
29
+ def enqueue(worker_class, *args)
30
+ current.enqueue worker_class, *args
31
+ end
32
+
33
+ def background_call(instance, method_name)
34
+ current.background_call(instance, method_name)
26
35
  end
27
- @@current = self
36
+ end
37
+
38
+ def initialize
39
+ @strategy = self.class.default_strategy.new
40
+ @reporter = self.class.default_reporter.new
28
41
  end
29
42
 
30
43
  def enqueue(worker_class, *args)
@@ -34,5 +47,9 @@ module Qmin
34
47
  def background_call(instance, method_name)
35
48
  @strategy.background_call(instance, method_name)
36
49
  end
50
+
51
+ def report(exception)
52
+ @reporter.report(exception)
53
+ end
37
54
  end
38
55
  end
@@ -0,0 +1,9 @@
1
+ module Qmin
2
+ module Reporting
3
+ class Inline
4
+ def report(exception)
5
+ raise exception
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,91 @@
1
+ require 'mail'
2
+
3
+ module Qmin
4
+ module Reporting
5
+ class Mail
6
+
7
+ class << self
8
+ def setup_delivery(delivery_method, delivery_options = {})
9
+ @delivery_method = delivery_method
10
+ @delivery_options = delivery_options
11
+ end
12
+
13
+ def delivery_method
14
+ @delivery_method
15
+ end
16
+
17
+ def delivery_options
18
+ @delivery_options
19
+ end
20
+
21
+ def setup_mail(to, from)
22
+ @mail_to = to
23
+ @mail_from = from
24
+ end
25
+
26
+ def mail_to
27
+ @mail_to
28
+ end
29
+
30
+ def mail_from
31
+ @mail_from
32
+ end
33
+ end
34
+
35
+ def report(exception)
36
+ deliver(mail(exception))
37
+ end
38
+
39
+ private
40
+
41
+ def mail(exception)
42
+ MailBuilder.new(exception, self.class.mail_to, self.class.mail_from).build
43
+ end
44
+
45
+ def deliver(mail)
46
+ if self.class.delivery_method && self.class.delivery_options
47
+ mail.delivery_method(self.class.delivery_method, self.class.delivery_options)
48
+ end
49
+
50
+ mail.deliver
51
+ end
52
+
53
+
54
+ class MailBuilder
55
+ def initialize(exception, mail_to, mail_from)
56
+ @exception, @mail_to, @mail_from = exception, mail_to, mail_from
57
+ end
58
+
59
+ attr_reader :exception, :mail_to, :mail_from
60
+
61
+ def build
62
+ mail = ::Mail.new
63
+
64
+ mail.to mail_to
65
+ mail.from mail_from
66
+ mail.subject subject
67
+ mail.body clean_backtrace.join("\n")
68
+
69
+ mail
70
+ end
71
+
72
+ private
73
+
74
+ def subject
75
+ "[ERROR] Qmin Report: #{exception.message}"
76
+ end
77
+
78
+ # copied from exception_notification gem
79
+ # http://github.com/smartinez87/exception_notification
80
+ def clean_backtrace
81
+ if defined?(Rails) && Rails.respond_to?(:backtrace_cleaner)
82
+ Rails.backtrace_cleaner.send(:filter, exception.backtrace)
83
+ else
84
+ exception.backtrace
85
+ end
86
+ end
87
+ end
88
+
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,8 @@
1
+ module Qmin
2
+ module Reporting
3
+ class Noop
4
+ def report(exception)
5
+ end
6
+ end
7
+ end
8
+ end
@@ -12,8 +12,12 @@ module Qmin
12
12
  end
13
13
 
14
14
  def perform
15
- instance = @klass.find(@id)
16
- instance.send(::Qmin.method_name_for_instance(instance, @method_name))
15
+ begin
16
+ instance = @klass.find(@id)
17
+ instance.send(::Qmin.method_name_for_instance(instance, @method_name))
18
+ rescue => e
19
+ ::Qmin::Qmin.current.report(e)
20
+ end
17
21
  end
18
22
  end
19
23
  end
@@ -1,3 +1,3 @@
1
1
  module Qmin
2
- VERSION = '0.0.7'
2
+ VERSION = '0.0.8'
3
3
  end
@@ -22,4 +22,5 @@ Gem::Specification.new do |spec|
22
22
  spec.add_development_dependency 'rake'
23
23
  spec.add_development_dependency 'rspec'
24
24
  spec.add_development_dependency 'mocha'
25
+ spec.add_development_dependency 'mail'
25
26
  end
@@ -8,26 +8,6 @@ describe Qmin do
8
8
  defined?(Qmin::Strategy::Resque).should eql('constant')
9
9
  end
10
10
 
11
- describe 'initialize' do
12
- it 'raises error if no strategy defined' do
13
- Qmin::Qmin.default_strategy = nil
14
-
15
- lambda {
16
- Qmin::Qmin.new
17
- }.should raise_error(Qmin::MustDefineStrategyError)
18
- end
19
-
20
- it 'raises error for current if no strategy defined' do
21
- # reset strategies
22
- Qmin::Qmin.default_strategy = nil
23
- Qmin::Qmin.send :class_variable_set, :@@current, nil
24
-
25
- lambda {
26
- Qmin::Qmin.current
27
- }.should raise_error(Qmin::MustDefineStrategyError)
28
- end
29
- end
30
-
31
11
  describe 'background_method' do
32
12
  it 'aliases background methods'do
33
13
  subject = BackgroundTestClass.new
@@ -51,8 +31,6 @@ describe Qmin do
51
31
 
52
32
  describe 'enqueue' do
53
33
  it 'enqueues job' do
54
- Qmin::Qmin.new(Qmin::Strategy::Inline)
55
-
56
34
  TestJob.expects(:perform).with(1,2,3)
57
35
  Qmin::Qmin.enqueue TestJob, 1,2,3
58
36
  end
@@ -0,0 +1,39 @@
1
+ require_relative '../../spec_helper'
2
+ require_relative '../../../lib/qmin'
3
+
4
+ describe 'Qmin::Reporting::Inline' do
5
+ let(:error_producer){ TestClass.new(123) }
6
+
7
+ it 'raises error with default inline strategy' do
8
+ lambda{
9
+ error_producer.raise_error
10
+ }.should raise_error(TestClass::CustomError)
11
+ end
12
+
13
+ it 'raises no error with noop strategy' do
14
+ Qmin::Qmin.default_strategy = Qmin::Strategy::Noop
15
+ lambda{
16
+ error_producer.raise_error
17
+ }.should_not raise_error(TestClass::CustomError)
18
+ end
19
+
20
+ describe 'resque strategy' do
21
+ before do
22
+ Qmin::Qmin.default_strategy = Qmin::Strategy::Resque
23
+ end
24
+
25
+ it 'raises no error with resque strategy when enqueueing the job' do
26
+ lambda{
27
+ error_producer.raise_error
28
+ }.should_not raise_error(TestClass::CustomError)
29
+ end
30
+
31
+ it 'raises error when job is performing' do
32
+ lambda{
33
+ Qmin::Resque::BackgroundCallJob.new(TestClass, :raise_error, error_producer.id).perform
34
+ }.should raise_error(TestClass::CustomError)
35
+ end
36
+ end
37
+
38
+ end
39
+
@@ -0,0 +1,46 @@
1
+ require_relative '../../spec_helper'
2
+ require_relative '../../../lib/qmin'
3
+
4
+ describe 'Qmin::Reporting::Mail' do
5
+
6
+ before do
7
+ Qmin::Reporting::Mail.setup_delivery :test
8
+ Qmin::Reporting::Mail.setup_mail 'receiver@example.com', 'error-notification@mydomain.com'
9
+ Qmin::Qmin.default_reporter = Qmin::Reporting::Mail
10
+ end
11
+
12
+ after do
13
+ Mail::TestMailer.deliveries.clear
14
+ Qmin::Qmin.default_reporter = nil
15
+ end
16
+
17
+ let(:error_producer){ TestClass.new(123) }
18
+
19
+ it 'raises error for inline strategy' do
20
+ lambda{
21
+ error_producer.raise_error
22
+ }.should raise_error(TestClass::CustomError)
23
+ end
24
+
25
+ describe 'resque strategy' do
26
+ before do
27
+ Qmin::Qmin.default_strategy = Qmin::Strategy::Resque
28
+ end
29
+
30
+ it 'raises no error with resque strategy when enqueuing the job' do
31
+ lambda{
32
+ error_producer.raise_error
33
+ }.should_not raise_error(TestClass::CustomError)
34
+ end
35
+
36
+ it 'raises error when job is performing' do
37
+ lambda{
38
+ Qmin::Resque::BackgroundCallJob.new(TestClass, :raise_error, error_producer.id).perform
39
+ }.should_not raise_error(TestClass::CustomError)
40
+
41
+ Mail::TestMailer.deliveries.should_not be_empty
42
+ end
43
+ end
44
+
45
+
46
+ end
@@ -4,7 +4,7 @@ describe Qmin::Resque::BackgroundCallJob do
4
4
  let(:id){ 123 }
5
5
 
6
6
  before do
7
- Qmin::Qmin.new(Qmin::Strategy::Resque)
7
+ Qmin::Qmin.default_strategy = Qmin::Strategy::Resque
8
8
  end
9
9
 
10
10
  it 'calls method on instance' do
@@ -12,15 +12,11 @@ describe Qmin::Resque::BackgroundCallJob do
12
12
  end
13
13
 
14
14
  it 'calls method on instance wrapped in background_call_job' do
15
- Qmin::Qmin.new(Qmin::Strategy::Resque)
16
-
17
15
  BackgroundTestClass.new(id).action
18
16
  ::Resque.queue['qmin_resque_background_call_job_background_test_class_action'][0].should eql ({:class => Qmin::Resque::BackgroundCallJob, :args => ['BackgroundTestClass', :action, 123]})
19
17
  end
20
18
 
21
19
  it 'delegates perform to instance' do
22
- Qmin::Qmin.new(Qmin::Strategy::Resque)
23
-
24
20
  Qmin::Resque::BackgroundCallJob.any_instance.expects(:perform)
25
21
  Qmin::Resque::BackgroundCallJob.perform(BackgroundTestClass, 'action', 123)
26
22
  end
@@ -2,13 +2,15 @@ require File.expand_path '../../spec_helper', File.dirname(__FILE__)
2
2
 
3
3
  describe Qmin::Resque::BaseJob do
4
4
 
5
+ before do
6
+ Qmin::Qmin.default_strategy = Qmin::Strategy::Resque
7
+ end
8
+
5
9
  it 'performs test job' do
6
- Qmin::Qmin.new(Qmin::Strategy::Resque)
7
10
  TestJob.perform(10).should eql 10
8
11
  end
9
12
 
10
13
  it 'demands find method on model class' do
11
- Qmin::Qmin.new(Qmin::Strategy::Resque)
12
14
  lambda {
13
15
  Class.new(Qmin::Resque::BaseJob) do
14
16
  model Class
@@ -7,8 +7,13 @@ rescue LoadError
7
7
  # only available for ruby 1.9+ in non-CI environments
8
8
  end
9
9
 
10
+ require 'mail'
10
11
  require 'rspec/autorun'
11
12
 
13
+ Mail.defaults do
14
+ delivery_method :test
15
+ end
16
+
12
17
  # mock Resque behavior
13
18
  class Resque
14
19
  def self.enqueue_to(queue_name, worker, *args)
@@ -45,11 +50,13 @@ RSpec.configure do |config|
45
50
 
46
51
  config.before(:each) do
47
52
  Resque.reset_queue!
48
- Qmin::Qmin.new(Qmin::Strategy::Inline)
53
+ Mail::TestMailer.deliveries.clear
54
+ Qmin::Qmin.default_strategy = nil
55
+ Qmin::Qmin.default_reporter = nil
49
56
  end
50
57
 
51
58
  config.after(:each) do
52
- Qmin::Qmin.new(Qmin::Strategy::Inline)
59
+
53
60
  end
54
61
  end
55
62
 
@@ -67,6 +74,13 @@ class WorkerClass
67
74
  end
68
75
 
69
76
  class TestClass
77
+ class CustomError < StandardError
78
+ def initialize(msg = '')
79
+ super
80
+ end
81
+ end
82
+
83
+
70
84
  def action
71
85
  @id
72
86
  end
@@ -83,6 +97,11 @@ class TestClass
83
97
  @id = id
84
98
  end
85
99
  attr_reader :id
100
+
101
+ def raise_error
102
+ raise CustomError.new("Something went wrong with #{@id}")
103
+ end
104
+ background :raise_error
86
105
  end
87
106
 
88
107
  class BackgroundTestClass < TestClass
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qmin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - the-architect
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-01-10 00:00:00.000000000 Z
11
+ date: 2014-01-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - '>='
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: mail
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  description: Simple framwork to coordinate background tasks
70
84
  email:
71
85
  - marcel.scherf@epicteams.com
@@ -85,6 +99,9 @@ files:
85
99
  - lib/qmin/core_ext/class.rb
86
100
  - lib/qmin/core_ext/string.rb
87
101
  - lib/qmin/qmin.rb
102
+ - lib/qmin/reporting/inline.rb
103
+ - lib/qmin/reporting/mail.rb
104
+ - lib/qmin/reporting/noop.rb
88
105
  - lib/qmin/resque/background_call_job.rb
89
106
  - lib/qmin/resque/base_job.rb
90
107
  - lib/qmin/strategy/inline.rb
@@ -95,6 +112,8 @@ files:
95
112
  - spec/qmin/core_ext/class_spec.rb
96
113
  - spec/qmin/core_ext/string_spec.rb
97
114
  - spec/qmin/qmin_spec.rb
115
+ - spec/qmin/reporting/inline_spec.rb
116
+ - spec/qmin/reporting/mail_spec.rb
98
117
  - spec/qmin/resque/background_call_job_spec.rb
99
118
  - spec/qmin/resque/base_job_spec.rb
100
119
  - spec/qmin/strategy/inline_spec.rb
@@ -129,6 +148,8 @@ test_files:
129
148
  - spec/qmin/core_ext/class_spec.rb
130
149
  - spec/qmin/core_ext/string_spec.rb
131
150
  - spec/qmin/qmin_spec.rb
151
+ - spec/qmin/reporting/inline_spec.rb
152
+ - spec/qmin/reporting/mail_spec.rb
132
153
  - spec/qmin/resque/background_call_job_spec.rb
133
154
  - spec/qmin/resque/base_job_spec.rb
134
155
  - spec/qmin/strategy/inline_spec.rb