qmin 0.0.7 → 0.0.8

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: 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