dalliance 0.1.0 → 0.1.1
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.
- data/README.rdoc +5 -5
- data/dalliance.gemspec +4 -2
- data/lib/dalliance/progress_meter.rb +25 -10
- data/lib/dalliance/version.rb +1 -1
- data/lib/dalliance/workers/delayed_job.rb +13 -0
- data/lib/dalliance/workers/resque.rb +15 -0
- data/lib/dalliance/workers.rb +6 -0
- data/lib/dalliance.rb +8 -6
- data/spec/dalliance/{asynchronous_spec.rb → asynchronous_delayed_job_spec.rb} +15 -11
- data/spec/dalliance/asynchronous_resque_spec.rb +106 -0
- data/spec/spec_helper.rb +1 -0
- metadata +29 -8
data/README.rdoc
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
= dalliance
|
2
2
|
|
3
|
-
|
3
|
+
Background processing for ActiveRecord w/ a 'delayable' worker & a state_machine
|
4
4
|
|
5
|
-
|
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 '
|
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', '>=
|
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
|
-
|
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
|
-
|
37
|
-
|
49
|
+
_progress = (current_count.to_f / total_count.to_f * 100).to_i
|
50
|
+
|
38
51
|
#Handle an incorrect total_count...
|
39
|
-
|
52
|
+
_progress = 100 if _progress > 100
|
40
53
|
rescue
|
41
54
|
#what, are you diving by zero?
|
42
|
-
|
55
|
+
_progress = 0
|
43
56
|
end
|
57
|
+
|
58
|
+
_progress
|
44
59
|
end
|
45
60
|
|
46
61
|
def increment!
|
data/lib/dalliance/version.rb
CHANGED
@@ -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
|
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
|
-
:
|
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
|
-
|
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
|
-
|
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[:
|
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[:
|
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[:
|
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
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.
|
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-
|
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:
|
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:
|
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
|
-
|
127
|
-
|
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/
|
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/
|
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
|