dalliance 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -1,8 +1,8 @@
1
1
  = dalliance
2
2
 
3
- Opinionated background processing for ActiveRecord w/ delayed_job & state_machine
3
+ Background processing for ActiveRecord w/ a 'delayable' worker & a state_machine
4
4
 
5
- A simple wrapper for asynchronous processing w/ error handling & a progress_meter
5
+ Built in support for delayed_job or resque.
6
6
 
7
7
  == Getting Started
8
8
 
@@ -15,14 +15,14 @@ In your model:
15
15
  class Model < ActiveRecord::Base
16
16
  dalliance :process_method
17
17
  end
18
-
18
+
19
19
  process_method is the name of the method to invoke for background processing
20
20
  to kick it off just call dalliance_background_process
21
21
 
22
22
  Handle your migrations:
23
23
 
24
24
  rails g dalliance:progress_meter
25
-
25
+
26
26
  rails g dalliance:update model_name
27
27
 
28
28
  == ProgressMeter
@@ -33,7 +33,7 @@ Create a method called dalliance_progress_meter_total_count
33
33
  Inside process_method call dalliance_progress_meter.increment! after each iteration
34
34
 
35
35
  In your views you can then call dalliance_progress to get feedback on your asynchronous process
36
-
36
+
37
37
  == Copyright
38
38
 
39
39
  Copyright (c) 2012 Annkissam. See LICENSE for details.
data/dalliance.gemspec CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
9
9
  s.email = ["eric.sullivan@annkissam.com"]
10
10
  s.homepage = "https://github.com/annkissam/dalliance"
11
11
  s.summary = %q{ Wrapper for an ActiveRecord model with a single ascynhronous method }
12
- s.description = %q{ Background processing for ActiveRecord using a 'delay' method and a state_machine }
12
+ s.description = %q{ Background processing for ActiveRecord using a 'delayable' worker and a state_machine }
13
13
 
14
14
  s.rubyforge_project = "dalliance"
15
15
 
@@ -24,7 +24,9 @@ Gem::Specification.new do |s|
24
24
  s.add_dependency('state_machine')
25
25
 
26
26
  s.add_development_dependency('rspec')
27
- s.add_development_dependency('delayed_job', '>= 2.0.0')
27
+ s.add_development_dependency('delayed_job', '>= 3.0.0')
28
28
  s.add_development_dependency('delayed_job_active_record')
29
29
  s.add_development_dependency('sqlite3')
30
+
31
+ s.add_development_dependency('resque')
30
32
  end
@@ -3,7 +3,7 @@ require 'active_record'
3
3
  module Dalliance
4
4
  class ProgressMeter < ::ActiveRecord::Base
5
5
  self.table_name = 'dalliance_progress_meters'
6
-
6
+
7
7
  belongs_to :dalliance_progress_model, :polymorphic => true
8
8
 
9
9
  validates_presence_of :dalliance_progress_model
@@ -16,11 +16,11 @@ module Dalliance
16
16
  def current_count
17
17
  self[:current_count] ||= 0
18
18
  end
19
-
19
+
20
20
  def total_count
21
21
  self[:total_count] ||= 1
22
22
  end
23
-
23
+
24
24
  def total_count=(count)
25
25
  if count <= 0
26
26
  self[:total_count] = 1
@@ -28,19 +28,34 @@ module Dalliance
28
28
  self[:total_count] = count
29
29
  end
30
30
  end
31
-
32
- before_validation :calculate_progress
33
31
 
34
- def calculate_progress
32
+ #before_validation :calculate_progress
33
+ #
34
+ #def calculate_progress
35
+ # begin
36
+ # self.progress = (current_count.to_f / total_count.to_f * 100).to_i
37
+ #
38
+ # #Handle an incorrect total_count...
39
+ # self.progress = 100 if progress > 100
40
+ # rescue
41
+ # #what, are you diving by zero?
42
+ # self.progress = 0
43
+ # end
44
+ #end
45
+
46
+ #TODO: This is just a stopgap until I fix increment! to be thread-safe
47
+ def progress
35
48
  begin
36
- self.progress = (current_count.to_f / total_count.to_f * 100).to_i
37
-
49
+ _progress = (current_count.to_f / total_count.to_f * 100).to_i
50
+
38
51
  #Handle an incorrect total_count...
39
- self.progress = 100 if progress > 100
52
+ _progress = 100 if _progress > 100
40
53
  rescue
41
54
  #what, are you diving by zero?
42
- self.progress = 0
55
+ _progress = 0
43
56
  end
57
+
58
+ _progress
44
59
  end
45
60
 
46
61
  def increment!
@@ -2,7 +2,7 @@ module Dalliance
2
2
  module VERSION
3
3
  MAJOR = 0
4
4
  MINOR = 1
5
- TINY = 0
5
+ TINY = 1
6
6
  PRE = nil
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
@@ -0,0 +1,13 @@
1
+ module Dalliance
2
+ module Workers
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')
6
+ end
7
+
8
+ def perform
9
+ instance_klass.constantize.find(instance_id).dalliance_process(true)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,15 @@
1
+ module Dalliance
2
+ module Workers
3
+ class Resque
4
+ @queue = :dalliance
5
+
6
+ def self.enqueue(instance)
7
+ ::Resque.enqueue(self, instance.class.name, instance.id)
8
+ end
9
+
10
+ def self.perform(instance_klass, instance_id)
11
+ instance_klass.constantize.find(instance_id).dalliance_process(true)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,6 @@
1
+ module Dalliance
2
+ module Workers
3
+ autoload :DelayedJob, 'dalliance/workers/delayed_job'
4
+ autoload :Resque, 'dalliance/workers/resque'
5
+ end
6
+ end
data/lib/dalliance.rb CHANGED
@@ -4,6 +4,7 @@ if defined?(Rails::Railtie)
4
4
  require 'dalliance/railtie'
5
5
  end
6
6
 
7
+ require 'dalliance/workers'
7
8
  require 'dalliance/progress_meter'
8
9
 
9
10
  module Dalliance
@@ -14,7 +15,7 @@ module Dalliance
14
15
  @options ||= {
15
16
  :background_processing => (defined?(Rails) ? Rails.env.production? : true),
16
17
  :dalliance_progress_meter_total_count_method => :dalliance_progress_meter_total_count,
17
- :delay_method => :delay
18
+ :worker_class => detect_worker_class
18
19
  }
19
20
  end
20
21
 
@@ -29,6 +30,11 @@ module Dalliance
29
30
  def configure
30
31
  yield(self) if block_given?
31
32
  end
33
+
34
+ def detect_worker_class
35
+ return Dalliance::Workers::DelayedJob if defined? ::Delayed::Job
36
+ return Dalliance::Workers::Resque if defined? ::Resque
37
+ end
32
38
  end
33
39
 
34
40
  included do
@@ -84,11 +90,7 @@ module Dalliance
84
90
  #Force backgound_processing w/ true
85
91
  def dalliance_background_process(backgound_processing = nil)
86
92
  if backgound_processing || (backgound_processing.nil? && Dalliance.background_processing?)
87
- if respond_to?(self.class.dalliance_options[:delay_method])
88
- self.send(self.class.dalliance_options[:delay_method]).dalliance_process(true)
89
- else
90
- raise NoMethodError.new("#{self.class.dalliance_options[:delay_method]} is undefined")
91
- end
93
+ self.class.dalliance_options[:worker_class].enqueue(self)
92
94
  else
93
95
  dalliance_process(false)
94
96
  end
@@ -7,10 +7,14 @@ describe DallianceModel do
7
7
  Dalliance.options[:background_processing] = true
8
8
  end
9
9
 
10
- context "no delay method" do
10
+ before do
11
+ Delayed::Job.destroy_all
12
+ end
13
+
14
+ context "no worker_class" do
11
15
  before(:all) do
12
16
  DallianceModel.dalliance_options[:dalliance_method] = :dalliance_success_method
13
- DallianceModel.dalliance_options[:delay_method] = :not_delay
17
+ DallianceModel.dalliance_options[:worker_class] = nil
14
18
  end
15
19
 
16
20
  it "should raise an error" do
@@ -21,7 +25,7 @@ describe DallianceModel do
21
25
  context "success" do
22
26
  before(:all) do
23
27
  DallianceModel.dalliance_options[:dalliance_method] = :dalliance_success_method
24
- DallianceModel.dalliance_options[:delay_method] = :delay
28
+ DallianceModel.dalliance_options[:worker_class] = Dalliance::Workers::DelayedJob
25
29
  end
26
30
 
27
31
  it "should not call the dalliance_method w/o a Delayed::Worker" do
@@ -34,7 +38,7 @@ describe DallianceModel do
34
38
 
35
39
  it "should call the dalliance_method w/ a Delayed::Worker" do
36
40
  subject.dalliance_background_process
37
- Delayed::Worker.new.work_off
41
+ Delayed::Worker.new(:queues => [:dalliance]).work_off
38
42
  subject.reload
39
43
 
40
44
  subject.should be_successful
@@ -43,7 +47,7 @@ describe DallianceModel do
43
47
 
44
48
  it "should set the dalliance_status to completed" do
45
49
  subject.dalliance_background_process
46
- Delayed::Worker.new.work_off
50
+ Delayed::Worker.new(:queues => [:dalliance]).work_off
47
51
  subject.reload
48
52
 
49
53
  subject.should be_completed
@@ -51,7 +55,7 @@ describe DallianceModel do
51
55
 
52
56
  it "should set the dalliance_progress to 100" do
53
57
  subject.dalliance_background_process
54
- Delayed::Worker.new.work_off
58
+ Delayed::Worker.new(:queues => [:dalliance]).work_off
55
59
  subject.reload
56
60
 
57
61
  subject.dalliance_progress.should == 100
@@ -61,20 +65,20 @@ describe DallianceModel do
61
65
  context "raise error" do
62
66
  before(:all) do
63
67
  DallianceModel.dalliance_options[:dalliance_method] = :dalliance_error_method
64
- DallianceModel.dalliance_options[:delay_method] = :delay
68
+ DallianceModel.dalliance_options[:worker_class] = Dalliance::Workers::DelayedJob
65
69
  end
66
70
 
67
71
  it "should NOT raise an error" do
68
72
  subject.dalliance_background_process
69
73
 
70
- Delayed::Worker.new.work_off
74
+ Delayed::Worker.new(:queues => [:dalliance]).work_off
71
75
 
72
76
  Delayed::Job.count.should == 0
73
77
  end
74
78
 
75
79
  it "should store the error" do
76
80
  subject.dalliance_background_process
77
- Delayed::Worker.new.work_off
81
+ Delayed::Worker.new(:queues => [:dalliance]).work_off
78
82
  subject.reload
79
83
 
80
84
  subject.dalliance_error_hash.should_not be_empty
@@ -85,7 +89,7 @@ describe DallianceModel do
85
89
 
86
90
  it "should set the dalliance_status to processing_error" do
87
91
  subject.dalliance_background_process
88
- Delayed::Worker.new.work_off
92
+ Delayed::Worker.new(:queues => [:dalliance]).work_off
89
93
  subject.reload
90
94
 
91
95
  subject.should be_processing_error
@@ -93,7 +97,7 @@ describe DallianceModel do
93
97
 
94
98
  it "should set the dalliance_progress to 0" do
95
99
  subject.dalliance_background_process
96
- Delayed::Worker.new.work_off
100
+ Delayed::Worker.new(:queues => [:dalliance]).work_off
97
101
  subject.reload
98
102
 
99
103
  subject.dalliance_progress.should == 0
@@ -0,0 +1,106 @@
1
+ require 'spec_helper'
2
+
3
+ describe DallianceModel do
4
+ subject { DallianceModel.create }
5
+
6
+ before(:all) do
7
+ Dalliance.options[:background_processing] = true
8
+ end
9
+
10
+ before do
11
+ Resque.remove_queue(:dalliance)
12
+ end
13
+
14
+ context "no worker_class" do
15
+ before(:all) do
16
+ DallianceModel.dalliance_options[:dalliance_method] = :dalliance_success_method
17
+ DallianceModel.dalliance_options[:worker_class] = nil
18
+ end
19
+
20
+ it "should raise an error" do
21
+ expect { subject.dalliance_background_process }.to raise_error(NoMethodError)
22
+ end
23
+ end
24
+
25
+ context "success" do
26
+ before(:all) do
27
+ DallianceModel.dalliance_options[:dalliance_method] = :dalliance_success_method
28
+ DallianceModel.dalliance_options[:worker_class] = Dalliance::Workers::Resque
29
+ end
30
+
31
+ it "should not call the dalliance_method w/o a Delayed::Worker" do
32
+ subject.dalliance_background_process
33
+ subject.reload
34
+
35
+ subject.should_not be_successful
36
+ Resque.size(:dalliance).should == 1
37
+ end
38
+
39
+ it "should call the dalliance_method w/ a Delayed::Worker" do
40
+ subject.dalliance_background_process
41
+ Resque::Worker.new(:dalliance).process
42
+ subject.reload
43
+
44
+ subject.should be_successful
45
+ Resque.size(:dalliance).should == 0
46
+ end
47
+
48
+ it "should set the dalliance_status to completed" do
49
+ subject.dalliance_background_process
50
+ Resque::Worker.new(:dalliance).process
51
+ subject.reload
52
+
53
+ subject.should be_completed
54
+ end
55
+
56
+ it "should set the dalliance_progress to 100" do
57
+ subject.dalliance_background_process
58
+ Resque::Worker.new(:dalliance).process
59
+ subject.reload
60
+
61
+ subject.dalliance_progress.should == 100
62
+ end
63
+ end
64
+
65
+ context "raise error" do
66
+ before(:all) do
67
+ DallianceModel.dalliance_options[:dalliance_method] = :dalliance_error_method
68
+ DallianceModel.dalliance_options[:worker_class] = Dalliance::Workers::Resque
69
+ end
70
+
71
+ it "should NOT raise an error" do
72
+ subject.dalliance_background_process
73
+
74
+ Resque::Worker.new(:dalliance).process
75
+
76
+ Resque.size(:dalliance).should == 0
77
+ end
78
+
79
+ it "should store the error" do
80
+ subject.dalliance_background_process
81
+ Resque::Worker.new(:dalliance).process
82
+ subject.reload
83
+
84
+ subject.dalliance_error_hash.should_not be_empty
85
+ subject.dalliance_error_hash[:error].should == RuntimeError.name #We store the class name...
86
+ subject.dalliance_error_hash[:message].should == 'RuntimeError'
87
+ subject.dalliance_error_hash[:backtrace].should_not be_blank
88
+ end
89
+
90
+ it "should set the dalliance_status to processing_error" do
91
+ subject.dalliance_background_process
92
+ Resque::Worker.new(:dalliance).process
93
+ subject.reload
94
+
95
+ subject.should be_processing_error
96
+ end
97
+
98
+ it "should set the dalliance_progress to 0" do
99
+ subject.dalliance_background_process
100
+ Resque::Worker.new(:dalliance).process
101
+ subject.reload
102
+
103
+ subject.dalliance_progress.should == 0
104
+ end
105
+ end
106
+ end
data/spec/spec_helper.rb CHANGED
@@ -8,6 +8,7 @@ require 'state_machine'
8
8
  #Required for testing...
9
9
  require 'delayed_job'
10
10
  require 'delayed_job_active_record'
11
+ require 'resque'
11
12
 
12
13
  require 'dalliance'
13
14
 
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.0
4
+ version: 0.1.1
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-08-17 00:00:00.000000000 Z
12
+ date: 2012-09-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -82,7 +82,7 @@ dependencies:
82
82
  requirements:
83
83
  - - ! '>='
84
84
  - !ruby/object:Gem::Version
85
- version: 2.0.0
85
+ version: 3.0.0
86
86
  type: :development
87
87
  prerelease: false
88
88
  version_requirements: !ruby/object:Gem::Requirement
@@ -90,7 +90,7 @@ dependencies:
90
90
  requirements:
91
91
  - - ! '>='
92
92
  - !ruby/object:Gem::Version
93
- version: 2.0.0
93
+ version: 3.0.0
94
94
  - !ruby/object:Gem::Dependency
95
95
  name: delayed_job_active_record
96
96
  requirement: !ruby/object:Gem::Requirement
@@ -123,8 +123,24 @@ dependencies:
123
123
  - - ! '>='
124
124
  - !ruby/object:Gem::Version
125
125
  version: '0'
126
- description: ! ' Background processing for ActiveRecord using a ''delay'' method and
127
- a state_machine '
126
+ - !ruby/object:Gem::Dependency
127
+ name: resque
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ description: ! ' Background processing for ActiveRecord using a ''delayable'' worker
143
+ and a state_machine '
128
144
  email:
129
145
  - eric.sullivan@annkissam.com
130
146
  executables: []
@@ -143,11 +159,15 @@ files:
143
159
  - lib/dalliance/railtie.rb
144
160
  - lib/dalliance/schema.rb
145
161
  - lib/dalliance/version.rb
162
+ - lib/dalliance/workers.rb
163
+ - lib/dalliance/workers/delayed_job.rb
164
+ - lib/dalliance/workers/resque.rb
146
165
  - lib/generators/dalliance/progress_meter/progress_meter_generator.rb
147
166
  - lib/generators/dalliance/progress_meter/templates/migration.rb
148
167
  - lib/generators/dalliance/update/templates/migration.rb.erb
149
168
  - lib/generators/dalliance/update/update_generator.rb
150
- - spec/dalliance/asynchronous_spec.rb
169
+ - spec/dalliance/asynchronous_delayed_job_spec.rb
170
+ - spec/dalliance/asynchronous_resque_spec.rb
151
171
  - spec/dalliance/dalliance_spec.rb
152
172
  - spec/dalliance/synchronous_spec.rb
153
173
  - spec/spec_helper.rb
@@ -177,7 +197,8 @@ signing_key:
177
197
  specification_version: 3
178
198
  summary: Wrapper for an ActiveRecord model with a single ascynhronous method
179
199
  test_files:
180
- - spec/dalliance/asynchronous_spec.rb
200
+ - spec/dalliance/asynchronous_delayed_job_spec.rb
201
+ - spec/dalliance/asynchronous_resque_spec.rb
181
202
  - spec/dalliance/dalliance_spec.rb
182
203
  - spec/dalliance/synchronous_spec.rb
183
204
  - spec/spec_helper.rb