dalliance 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,6 +3,7 @@ module Dalliance
3
3
  def add_dalliance
4
4
  column :dalliance_error_hash, :text, {}
5
5
  column :dalliance_status, :string, {:null => false, :default => 'pending'}
6
+ column :dalliance_duration, :integer, {}
6
7
  end
7
8
  end
8
9
  end
@@ -2,7 +2,7 @@ module Dalliance
2
2
  module VERSION
3
3
  MAJOR = 0
4
4
  MINOR = 1
5
- TINY = 2
5
+ TINY = 3
6
6
  PRE = nil
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
@@ -1,8 +1,8 @@
1
1
  module Dalliance
2
2
  module Workers
3
3
  class DelayedJob < Struct.new(:instance_klass, :instance_id)
4
- def self.enqueue(instance)
5
- ::Delayed::Job.enqueue(self.new(instance.class.name, instance.id), :queue => 'dalliance')
4
+ def self.enqueue(instance, queue = 'dalliance')
5
+ ::Delayed::Job.enqueue(self.new(instance.class.name, instance.id), :queue => queue)
6
6
  end
7
7
 
8
8
  def perform
@@ -1,10 +1,8 @@
1
1
  module Dalliance
2
2
  module Workers
3
3
  class Resque
4
- @queue = :dalliance
5
-
6
- def self.enqueue(instance)
7
- ::Resque.enqueue(self, instance.class.name, instance.id)
4
+ def self.enqueue(instance, queue = 'dalliance')
5
+ ::Resque.enqueue_to(queue, self, instance.class.name, instance.id)
8
6
  end
9
7
 
10
8
  def self.perform(instance_klass, instance_id)
data/lib/dalliance.rb CHANGED
@@ -8,6 +8,7 @@ require 'dalliance/workers'
8
8
  require 'dalliance/progress_meter'
9
9
 
10
10
  require 'state_machine'
11
+ require 'benchmark'
11
12
 
12
13
  module Dalliance
13
14
  extend ActiveSupport::Concern
@@ -16,19 +17,43 @@ module Dalliance
16
17
  def options
17
18
  @options ||= {
18
19
  :background_processing => (defined?(Rails) ? Rails.env.production? : true),
20
+ :dalliance_progress_meter => true,
19
21
  :dalliance_progress_meter_total_count_method => :dalliance_progress_meter_total_count,
20
- :worker_class => detect_worker_class
22
+ :worker_class => detect_worker_class,
23
+ :queue => 'dalliance',
24
+ :logger => detect_logger,
25
+ :duration_column => nil
21
26
  }
22
27
  end
23
28
 
24
- def background_processing?
25
- options[:background_processing]
26
- end
27
-
28
29
  def background_processing=(value)
29
30
  options[:background_processing] = value
30
31
  end
31
32
 
33
+ def dalliance_progress_meter=(value)
34
+ options[:dalliance_progress_meter] = value
35
+ end
36
+
37
+ def dalliance_progress_meter_total_count_method=(value)
38
+ options[:dalliance_progress_meter_total_count_method] = value
39
+ end
40
+
41
+ def worker_class=(value)
42
+ options[:worker_class] = value
43
+ end
44
+
45
+ def queue=(value)
46
+ options[:queue] = value
47
+ end
48
+
49
+ def logger=(value)
50
+ options[:logger] = value
51
+ end
52
+
53
+ def duration_column=(value)
54
+ options[:duration_column] = value
55
+ end
56
+
32
57
  def configure
33
58
  yield(self) if block_given?
34
59
  end
@@ -37,6 +62,16 @@ module Dalliance
37
62
  return Dalliance::Workers::DelayedJob if defined? ::Delayed::Job
38
63
  return Dalliance::Workers::Resque if defined? ::Resque
39
64
  end
65
+
66
+ def detect_logger
67
+ if defined?(ActiveRecord)
68
+ ActiveRecord::Base.logger
69
+ elsif defined?(Rails)
70
+ Rails.logger
71
+ else
72
+ ::Logger.new(STDOUT)
73
+ end
74
+ end
40
75
  end
41
76
 
42
77
  included do
@@ -91,8 +126,8 @@ module Dalliance
91
126
 
92
127
  #Force backgound_processing w/ true
93
128
  def dalliance_background_process(backgound_processing = nil)
94
- if backgound_processing || (backgound_processing.nil? && Dalliance.background_processing?)
95
- self.class.dalliance_options[:worker_class].enqueue(self)
129
+ if backgound_processing || (backgound_processing.nil? && self.class.dalliance_options[:background_processing])
130
+ self.class.dalliance_options[:worker_class].enqueue(self, self.class.dalliance_options[:queue])
96
131
  else
97
132
  dalliance_process(false)
98
133
  end
@@ -100,10 +135,14 @@ module Dalliance
100
135
 
101
136
  #backgound_processing == false will re-raise any exceptions
102
137
  def dalliance_process(backgound_processing = false)
138
+ start_time = Time.now
139
+
103
140
  begin
104
141
  start_dalliance!
105
142
 
106
- build_dalliance_progress_meter(:total_count => calculate_dalliance_progress_meter_total_count).save!
143
+ if self.class.dalliance_options[:dalliance_progress_meter]
144
+ build_dalliance_progress_meter(:total_count => calculate_dalliance_progress_meter_total_count).save!
145
+ end
107
146
 
108
147
  self.send(self.class.dalliance_options[:dalliance_method])
109
148
 
@@ -117,11 +156,21 @@ module Dalliance
117
156
  #Don't raise the error if we're backgound_processing...
118
157
  raise e unless backgound_processing
119
158
  ensure
120
- if dalliance_progress_meter
159
+ if self.class.dalliance_options[:dalliance_progress_meter] && dalliance_progress_meter
121
160
  #Works with optimistic locking...
122
161
  Dalliance::ProgressMeter.delete(dalliance_progress_meter.id)
123
162
  self.dalliance_progress_meter = nil
124
163
  end
164
+
165
+ duration = Time.now - start_time
166
+
167
+ if self.class.dalliance_options[:logger]
168
+ self.class.dalliance_options[:logger].info("[dalliance] #{self.class.name}(#{id}) - #{dalliance_status} #{duration.to_i}")
169
+ end
170
+
171
+ if self.class.dalliance_options[:duration_column]
172
+ self.class.where(id: self.id).update_all(self.class.dalliance_options[:duration_column] => duration.to_i)
173
+ end
125
174
  end
126
175
  end
127
176
 
@@ -129,7 +178,7 @@ module Dalliance
129
178
  if completed?
130
179
  100
131
180
  else
132
- if dalliance_progress_meter
181
+ if self.class.dalliance_options[:dalliance_progress_meter] && dalliance_progress_meter
133
182
  dalliance_progress_meter.progress
134
183
  else
135
184
  0
@@ -4,7 +4,7 @@ describe DallianceModel do
4
4
  subject { DallianceModel.create }
5
5
 
6
6
  before(:all) do
7
- Dalliance.options[:background_processing] = true
7
+ DallianceModel.dalliance_options[:background_processing] = true
8
8
  end
9
9
 
10
10
  before do
@@ -15,6 +15,7 @@ describe DallianceModel do
15
15
  before(:all) do
16
16
  DallianceModel.dalliance_options[:dalliance_method] = :dalliance_success_method
17
17
  DallianceModel.dalliance_options[:worker_class] = nil
18
+ DallianceModel.dalliance_options[:queue] = 'dalliance'
18
19
  end
19
20
 
20
21
  it "should raise an error" do
@@ -26,6 +27,8 @@ describe DallianceModel do
26
27
  before(:all) do
27
28
  DallianceModel.dalliance_options[:dalliance_method] = :dalliance_success_method
28
29
  DallianceModel.dalliance_options[:worker_class] = Dalliance::Workers::DelayedJob
30
+ DallianceModel.dalliance_options[:queue] = 'dalliance'
31
+ DallianceModel.dalliance_options[:duration_column] = 'dalliance_duration'
29
32
  end
30
33
 
31
34
  it "should not call the dalliance_method w/o a Delayed::Worker" do
@@ -60,12 +63,49 @@ describe DallianceModel do
60
63
 
61
64
  subject.dalliance_progress.should == 100
62
65
  end
66
+
67
+ it "should set the dalliance_duration" do
68
+ subject.dalliance_duration.should == nil
69
+
70
+ subject.dalliance_background_process
71
+ Delayed::Worker.new(:queues => [:dalliance]).work_off
72
+ subject.reload
73
+
74
+ subject.dalliance_duration.should_not == nil
75
+ end
76
+
77
+ context "another_queue" do
78
+ let(:queue) { 'dalliance_2'}
79
+
80
+ before(:all) do
81
+ DallianceModel.dalliance_options[:queue] = queue
82
+ end
83
+
84
+ it "should NOT call the dalliance_method w/ a Delayed::Worker (different queue)" do
85
+ subject.dalliance_background_process
86
+ Delayed::Worker.new(:queues => [:dalliance]).work_off
87
+ subject.reload
88
+
89
+ subject.should_not be_successful
90
+ Delayed::Job.count.should == 1
91
+ end
92
+
93
+ it "should call the dalliance_method w/ a Delayed::Worker (same queue)" do
94
+ subject.dalliance_background_process
95
+ Delayed::Worker.new(:queues => [queue]).work_off
96
+ subject.reload
97
+
98
+ subject.should be_successful
99
+ Delayed::Job.count.should == 0
100
+ end
101
+ end
63
102
  end
64
103
 
65
104
  context "raise error" do
66
105
  before(:all) do
67
106
  DallianceModel.dalliance_options[:dalliance_method] = :dalliance_error_method
68
107
  DallianceModel.dalliance_options[:worker_class] = Dalliance::Workers::DelayedJob
108
+ DallianceModel.dalliance_options[:queue] = 'dalliance'
69
109
  end
70
110
 
71
111
  it "should NOT raise an error" do
@@ -4,7 +4,7 @@ describe DallianceModel do
4
4
  subject { DallianceModel.create }
5
5
 
6
6
  before(:all) do
7
- Dalliance.options[:background_processing] = true
7
+ DallianceModel.dalliance_options[:background_processing] = true
8
8
  end
9
9
 
10
10
  before do
@@ -15,6 +15,7 @@ describe DallianceModel do
15
15
  before(:all) do
16
16
  DallianceModel.dalliance_options[:dalliance_method] = :dalliance_success_method
17
17
  DallianceModel.dalliance_options[:worker_class] = nil
18
+ DallianceModel.dalliance_options[:queue] = 'dalliance'
18
19
  end
19
20
 
20
21
  it "should raise an error" do
@@ -26,6 +27,8 @@ describe DallianceModel do
26
27
  before(:all) do
27
28
  DallianceModel.dalliance_options[:dalliance_method] = :dalliance_success_method
28
29
  DallianceModel.dalliance_options[:worker_class] = Dalliance::Workers::Resque
30
+ DallianceModel.dalliance_options[:queue] = 'dalliance'
31
+ DallianceModel.dalliance_options[:duration_column] = 'dalliance_duration'
29
32
  end
30
33
 
31
34
  it "should not call the dalliance_method w/o a Delayed::Worker" do
@@ -60,12 +63,53 @@ describe DallianceModel do
60
63
 
61
64
  subject.dalliance_progress.should == 100
62
65
  end
66
+
67
+ it "should set the dalliance_duration" do
68
+ subject.dalliance_duration.should == nil
69
+
70
+ subject.dalliance_background_process
71
+ Resque::Worker.new(:dalliance).process
72
+ subject.reload
73
+
74
+ subject.dalliance_duration.should_not == nil
75
+ end
76
+
77
+ context "another_queue" do
78
+ let(:queue) { 'dalliance_2'}
79
+
80
+ before(:all) do
81
+ DallianceModel.dalliance_options[:queue] = queue
82
+ end
83
+
84
+ before do
85
+ Resque.remove_queue(queue)
86
+ end
87
+
88
+ it "should NOT call the dalliance_method w/ a Delayed::Worker (different queue)" do
89
+ subject.dalliance_background_process
90
+ Resque::Worker.new(:dalliance).process
91
+ subject.reload
92
+
93
+ subject.should_not be_successful
94
+ Resque.size(queue).should == 1
95
+ end
96
+
97
+ it "should call the dalliance_method w/ a Delayed::Worker (same queue)" do
98
+ subject.dalliance_background_process
99
+ Resque::Worker.new(queue).process
100
+ subject.reload
101
+
102
+ subject.should be_successful
103
+ Resque.size(queue).should == 0
104
+ end
105
+ end
63
106
  end
64
107
 
65
108
  context "raise error" do
66
109
  before(:all) do
67
110
  DallianceModel.dalliance_options[:dalliance_method] = :dalliance_error_method
68
111
  DallianceModel.dalliance_options[:worker_class] = Dalliance::Workers::Resque
112
+ DallianceModel.dalliance_options[:queue] = 'dalliance'
69
113
  end
70
114
 
71
115
  it "should NOT raise an error" do
@@ -2,56 +2,66 @@ require 'spec_helper'
2
2
 
3
3
  describe DallianceModel do
4
4
  subject { DallianceModel.create }
5
-
5
+
6
6
  before(:all) do
7
- Dalliance.options[:background_processing] = false
7
+ DallianceModel.dalliance_options[:background_processing] = false
8
+ DallianceModel.dalliance_options[:duration_column] = 'dalliance_duration'
8
9
  end
9
-
10
+
10
11
  context "success" do
11
12
  before(:all) do
12
13
  DallianceModel.dalliance_options[:dalliance_method] = :dalliance_success_method
13
14
  end
14
-
15
+
15
16
  it "should call the dalliance_method" do
16
17
  lambda { subject.dalliance_background_process }.should change(subject, :successful).from(false).to(true)
17
18
  end
18
-
19
+
19
20
  it "should set the dalliance_status to completed" do
20
21
  lambda { subject.dalliance_background_process }.should change(subject, :dalliance_status).from('pending').to('completed')
21
22
  end
22
-
23
+
23
24
  it "should set the dalliance_progress to 100" do
24
25
  lambda { subject.dalliance_background_process }.should change(subject, :dalliance_progress).from(0).to(100)
25
26
  end
27
+
28
+ it "should set the dalliance_duration" do
29
+ subject.dalliance_duration.should == nil
30
+
31
+ subject.dalliance_background_process
32
+ subject.reload
33
+
34
+ subject.dalliance_duration.should_not == nil
35
+ end
26
36
  end
27
-
37
+
28
38
  context "raise error" do
29
39
  before(:all) do
30
40
  DallianceModel.dalliance_options[:dalliance_method] = :dalliance_error_method
31
41
  end
32
-
42
+
33
43
  it "should raise an error" do
34
44
  expect { subject.dalliance_background_process }.to raise_error(RuntimeError)
35
45
  end
36
-
46
+
37
47
  it "should store the error" do
38
48
  expect { subject.dalliance_background_process }.to raise_error(RuntimeError)
39
-
49
+
40
50
  subject.dalliance_error_hash.should_not be_empty
41
51
  subject.dalliance_error_hash[:error].should == RuntimeError.name #We store the class name...
42
52
  subject.dalliance_error_hash[:message].should == 'RuntimeError'
43
53
  subject.dalliance_error_hash[:backtrace].should_not be_blank
44
54
  end
45
-
55
+
46
56
  it "should set the dalliance_status to processing_error" do
47
57
  expect { subject.dalliance_background_process }.to raise_error(RuntimeError)
48
-
58
+
49
59
  subject.should be_processing_error
50
60
  end
51
-
61
+
52
62
  it "should set the dalliance_progress to 0" do
53
63
  expect { subject.dalliance_background_process }.to raise_error(RuntimeError)
54
-
64
+
55
65
  subject.dalliance_progress.should == 0
56
66
  end
57
67
  end
@@ -16,7 +16,7 @@ ActiveRecord::Schema.define do
16
16
  end
17
17
 
18
18
  add_index :dalliance_progress_meters, [:dalliance_progress_model_id, :dalliance_progress_model_type], :name => 'by_dalliance_progress_model'
19
-
19
+
20
20
  create_table :delayed_jobs, :force => true do |table|
21
21
  table.integer :priority, :default => 0
22
22
  table.integer :attempts, :default => 0
@@ -29,13 +29,14 @@ ActiveRecord::Schema.define do
29
29
  table.string :queue
30
30
  table.timestamps
31
31
  end
32
-
32
+
33
33
  add_index :delayed_jobs, [:priority, :run_at], :name => 'delayed_jobs_priority'
34
34
 
35
35
  create_table :dalliance_models, :force => true do |t|
36
- t.text :dalliance_error_hash
37
- t.string :dalliance_status, :string, :null => false, :default => 'pending'
38
-
36
+ t.text :dalliance_error_hash
37
+ t.string :dalliance_status, :string, :null => false, :default => 'pending'
38
+ t.integer :dalliance_duration
39
+
39
40
  t.boolean :successful, :default => false
40
41
  end
41
42
  end
@@ -44,13 +45,14 @@ end
44
45
  class DallianceModel < ActiveRecord::Base
45
46
  #We're not using the railtie in tests...
46
47
  include Dalliance::Glue
47
-
48
- dalliance :dalliance_success_method
48
+
49
+ dalliance :dalliance_success_method,
50
+ :logger => nil
49
51
 
50
52
  def dalliance_success_method
51
53
  update_attribute(:successful, true)
52
54
  end
53
-
55
+
54
56
  def dalliance_error_method
55
57
  raise RuntimeError
56
58
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dalliance
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-19 00:00:00.000000000 Z
12
+ date: 2012-12-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord