massive 0.3.0 → 0.4.0
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 +4 -4
- data/Gemfile.lock +1 -1
- data/lib/massive.rb +9 -0
- data/lib/massive/file_serializer.rb +9 -0
- data/lib/massive/job.rb +21 -1
- data/lib/massive/process.rb +1 -1
- data/lib/massive/process_serializer.rb +5 -0
- data/lib/massive/step.rb +1 -1
- data/lib/massive/version.rb +1 -1
- data/spec/models/massive/file_serializer_spec.rb +40 -0
- data/spec/models/massive/job_spec.rb +64 -0
- data/spec/models/massive/process_serializer_spec.rb +14 -0
- data/spec/models/massive/process_spec.rb +37 -75
- data/spec/models/massive/step_spec.rb +2 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d0ad236ec732665de7fcf03668e8ce4675da4344
|
4
|
+
data.tar.gz: acba7ff61e45ff129881fa0d86b49480eaa85912
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1c922037b0dc37a497a6cced3880e88436912e6d3c8ff35ab8fc80c18f3375fbf4262551ea66ad82b7c5d065d0b20cb168c752400c28382df774027423687fe3
|
7
|
+
data.tar.gz: 122c02cc041df10b737ac8d6457d2bda985bb2930037672df0da4febe828648a9029829c08161597e9a5def1442e3f176062856fb15f52b7d4b72965f3d3c3b7
|
data/Gemfile.lock
CHANGED
data/lib/massive.rb
CHANGED
@@ -22,6 +22,7 @@ module Massive
|
|
22
22
|
|
23
23
|
autoload :ProcessSerializer, 'massive/process_serializer'
|
24
24
|
autoload :StepSerializer, 'massive/step_serializer'
|
25
|
+
autoload :FileSerializer, 'massive/file_serializer'
|
25
26
|
|
26
27
|
module Authenticators
|
27
28
|
autoload :S3, 'massive/authenticators/s3'
|
@@ -33,6 +34,14 @@ module Massive
|
|
33
34
|
@redis ||= Resque.redis
|
34
35
|
end
|
35
36
|
|
37
|
+
def self.split_jobs
|
38
|
+
@split_jobs
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.split_jobs=(value)
|
42
|
+
@split_jobs = value
|
43
|
+
end
|
44
|
+
|
36
45
|
def self.storage_config
|
37
46
|
@storage_config
|
38
47
|
end
|
data/lib/massive/job.rb
CHANGED
@@ -26,7 +26,26 @@ module Massive
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def self.queue
|
29
|
-
|
29
|
+
if split_jobs
|
30
|
+
:"#{queue_prefix}_#{Kernel.rand(split_jobs) + 1}"
|
31
|
+
else
|
32
|
+
queue_prefix
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.queue_prefix(value=nil)
|
37
|
+
@queue_prefix = value if !value.nil?
|
38
|
+
@queue_prefix || :massive_job
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.split_jobs(value=nil)
|
42
|
+
@split_jobs = value if !value.nil?
|
43
|
+
@split_jobs.nil? ? Massive.split_jobs : @split_jobs
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.cancel_when_failed(value=nil)
|
47
|
+
@cancel_when_failed = value if !value.nil?
|
48
|
+
@cancel_when_failed
|
30
49
|
end
|
31
50
|
|
32
51
|
def enqueue
|
@@ -101,6 +120,7 @@ module Massive
|
|
101
120
|
step.save
|
102
121
|
notify(:failed)
|
103
122
|
|
123
|
+
process.cancel if self.class.cancel_when_failed
|
104
124
|
raise e
|
105
125
|
end
|
106
126
|
|
data/lib/massive/process.rb
CHANGED
@@ -3,10 +3,15 @@ module Massive
|
|
3
3
|
attributes :id, :created_at, :updated_at, :processed_percentage
|
4
4
|
attribute :completed?, key: :completed
|
5
5
|
|
6
|
+
has_one :file
|
6
7
|
has_many :steps
|
7
8
|
|
8
9
|
def id
|
9
10
|
object.id.to_s
|
10
11
|
end
|
12
|
+
|
13
|
+
def include_file?
|
14
|
+
object.respond_to?(:file)
|
15
|
+
end
|
11
16
|
end
|
12
17
|
end
|
data/lib/massive/step.rb
CHANGED
@@ -9,7 +9,7 @@ module Massive
|
|
9
9
|
include Massive::Locking
|
10
10
|
include Massive::Notifications
|
11
11
|
|
12
|
-
|
12
|
+
belongs_to :process, class_name: 'Massive::Process'
|
13
13
|
embeds_many :jobs, class_name: 'Massive::Job'
|
14
14
|
|
15
15
|
field :total_count, type: Integer
|
data/lib/massive/version.rb
CHANGED
@@ -0,0 +1,40 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Massive::FileSerializer do
|
4
|
+
let(:headers) { ['name', 'description', 'price'] }
|
5
|
+
let(:sample_data) { [['Some name', 'Some desc', 1234], ['Other name', 'Other desc', 5678]] }
|
6
|
+
let(:file) { Massive::File.new(url: 'http://some.url.com', encoding: 'utf8', col_sep: ';', total_count: 1234, use_headers: true, headers: headers, sample_data: sample_data) }
|
7
|
+
subject(:serialized) { described_class.new(file).as_json(root: false) }
|
8
|
+
|
9
|
+
it "serializes file id as string" do
|
10
|
+
serialized[:id].should eq(file.id.to_s)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "serializes url" do
|
14
|
+
serialized[:url].should eq(file.url)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "serializes encoding" do
|
18
|
+
serialized[:encoding].should eq(file.encoding)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "serializes col_sep" do
|
22
|
+
serialized[:col_sep].should eq(file.col_sep)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "serializes total_count" do
|
26
|
+
serialized[:total_count].should eq(file.total_count)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "serializes use_headers" do
|
30
|
+
serialized[:use_headers].should eq(file.use_headers)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "serializes headers" do
|
34
|
+
serialized[:headers].should eq(file.headers)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "serializes sample_data" do
|
38
|
+
serialized[:sample_data].should eq(file.sample_data)
|
39
|
+
end
|
40
|
+
end
|
@@ -8,6 +8,8 @@ describe Massive::Job do
|
|
8
8
|
let(:step) { process.steps.build }
|
9
9
|
subject(:job) { step.jobs.build }
|
10
10
|
|
11
|
+
before { job.stub(:process).and_return(process) }
|
12
|
+
|
11
13
|
describe ".perform" do
|
12
14
|
before do
|
13
15
|
Massive::Process.stub(:find_job).with(process.id, step.id, job.id).and_return(job)
|
@@ -20,9 +22,57 @@ describe Massive::Job do
|
|
20
22
|
end
|
21
23
|
|
22
24
|
describe ".queue" do
|
25
|
+
after { Massive::Job.queue_prefix(:massive_job) }
|
26
|
+
|
23
27
|
it "should be massive_job" do
|
24
28
|
Massive::Job.queue.should eq(:massive_job)
|
25
29
|
end
|
30
|
+
|
31
|
+
it "should use queue_prefix" do
|
32
|
+
Massive::Job.queue_prefix(:my_job_queue)
|
33
|
+
Massive::Job.queue.should eq(:my_job_queue)
|
34
|
+
end
|
35
|
+
|
36
|
+
context "when Massive.split_jobs is set to 100" do
|
37
|
+
before { Massive.split_jobs = 100 }
|
38
|
+
after { Massive.split_jobs = false }
|
39
|
+
|
40
|
+
it "should be massive_job_XXX where XXX is a random number" do
|
41
|
+
values = 10000.times.inject({}) do |memo, index|
|
42
|
+
match = Massive::Job.queue.to_s.match(/massive_job_(\d+)/)
|
43
|
+
memo[match[1].to_i] ||= 0
|
44
|
+
memo[match[1].to_i] += 1
|
45
|
+
memo
|
46
|
+
end
|
47
|
+
|
48
|
+
(1..100).each do |key|
|
49
|
+
expect(values.keys.sort).to include(key)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should use the queue prefix" do
|
54
|
+
Massive::Job.queue_prefix(:my_job_queue)
|
55
|
+
expect(Massive::Job.queue.to_s).to start_with('my_job_queue')
|
56
|
+
end
|
57
|
+
|
58
|
+
context "when Job split_jobs is set to 10" do
|
59
|
+
before { Massive::Job.split_jobs 200 }
|
60
|
+
after { Massive::Job.split_jobs false }
|
61
|
+
|
62
|
+
it "should be massive_job_XXX where XXX is a random number between 1 and 10" do
|
63
|
+
values = 10000.times.inject({}) do |memo, index|
|
64
|
+
match = Massive::Job.queue.to_s.match(/massive_job_(\d+)/)
|
65
|
+
memo[match[1].to_i] ||= 0
|
66
|
+
memo[match[1].to_i] += 1
|
67
|
+
memo
|
68
|
+
end
|
69
|
+
|
70
|
+
(1..200).each do |key|
|
71
|
+
expect(values.keys.sort).to include(key)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
26
76
|
end
|
27
77
|
|
28
78
|
describe "#enqueue" do
|
@@ -219,6 +269,20 @@ describe Massive::Job do
|
|
219
269
|
rescue StandardError, SignalException
|
220
270
|
end
|
221
271
|
end
|
272
|
+
|
273
|
+
context "when it is configured to cancel when failed" do
|
274
|
+
before { Massive::Job.cancel_when_failed true }
|
275
|
+
after { Massive::Job.cancel_when_failed false }
|
276
|
+
|
277
|
+
it "cancels the process" do
|
278
|
+
expect(process).to receive(:cancel)
|
279
|
+
|
280
|
+
begin
|
281
|
+
job.work
|
282
|
+
rescue StandardError, SignalException
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
222
286
|
end
|
223
287
|
|
224
288
|
context "when an error occurs" do
|
@@ -35,4 +35,18 @@ describe Massive::ProcessSerializer do
|
|
35
35
|
serialized[:completed].should be_false
|
36
36
|
end
|
37
37
|
end
|
38
|
+
|
39
|
+
context "when it does not respond to file" do
|
40
|
+
it "does not serializes file" do
|
41
|
+
serialized[:file].should be_blank
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "when it responds to file" do
|
46
|
+
let(:process) { Massive::FileProcess.new }
|
47
|
+
|
48
|
+
it "serializes file" do
|
49
|
+
serialized[:file].should be_present
|
50
|
+
end
|
51
|
+
end
|
38
52
|
end
|
@@ -1,81 +1,45 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Massive::Process do
|
4
|
-
subject(:process) { Massive::Process.
|
4
|
+
subject(:process) { Massive::Process.create }
|
5
5
|
|
6
6
|
describe "#enqueue_next" do
|
7
|
-
context "when there
|
8
|
-
let
|
9
|
-
let!(:second_step) { process.steps.build }
|
10
|
-
let!(:third_step) { process.steps.build }
|
7
|
+
context "when there is a next steps" do
|
8
|
+
let(:step) { process.steps.create }
|
11
9
|
|
12
10
|
before do
|
13
|
-
|
14
|
-
second_step.stub(:reload).and_return(second_step)
|
15
|
-
third_step.stub(:reload).and_return(third_step)
|
11
|
+
process.stub(:next_step).and_return(step)
|
16
12
|
end
|
17
13
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
process.enqueue_next
|
22
|
-
end
|
23
|
-
|
24
|
-
it "does not enqueue the other steps" do
|
25
|
-
second_step.should_not_receive(:enqueue)
|
26
|
-
third_step.should_not_receive(:enqueue)
|
27
|
-
process.enqueue_next
|
28
|
-
end
|
14
|
+
it "enqueues the step" do
|
15
|
+
step.should_receive(:enqueue)
|
16
|
+
process.enqueue_next
|
29
17
|
end
|
18
|
+
end
|
30
19
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
it "does not enqueue the first step" do
|
35
|
-
first_step.should_not_receive(:enqueue)
|
36
|
-
process.enqueue_next
|
37
|
-
end
|
38
|
-
|
39
|
-
it "enqueues the second step" do
|
40
|
-
second_step.should_receive(:enqueue)
|
41
|
-
process.enqueue_next
|
42
|
-
end
|
43
|
-
|
44
|
-
it "does not enqueue the third step" do
|
45
|
-
third_step.should_not_receive(:enqueue)
|
46
|
-
process.enqueue_next
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
context "and the first one is enqueued" do
|
51
|
-
before { first_step.stub(:enqueued?).and_return(true) }
|
52
|
-
|
53
|
-
it "does not enqueue the next step" do
|
54
|
-
second_step.should_not_receive(:enqueue)
|
55
|
-
process.enqueue_next
|
56
|
-
end
|
20
|
+
context "when there is no next step" do
|
21
|
+
before do
|
22
|
+
process.stub(:next_step).and_return(nil)
|
57
23
|
end
|
58
24
|
|
59
|
-
|
60
|
-
|
61
|
-
process.steps.each do |step|
|
62
|
-
step.finished_at = Time.now
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
it "does not enqueue any of the steps" do
|
67
|
-
process.steps.each do |step|
|
68
|
-
step.should_not_receive(:enqueue)
|
69
|
-
end
|
70
|
-
|
25
|
+
it "does not raise error" do
|
26
|
+
expect {
|
71
27
|
process.enqueue_next
|
72
|
-
|
28
|
+
}.to_not raise_error
|
73
29
|
end
|
74
30
|
end
|
75
31
|
end
|
76
32
|
|
77
33
|
describe "#next_step" do
|
78
|
-
let!(:step) { process.steps.
|
34
|
+
let!(:step) { process.steps.create }
|
35
|
+
|
36
|
+
before do
|
37
|
+
steps = double('Array')
|
38
|
+
process.stub(:steps).and_return(steps)
|
39
|
+
steps.stub(:not_completed).and_return(steps)
|
40
|
+
steps.stub(:not_started).and_return(steps)
|
41
|
+
steps.stub(:first).and_return(step)
|
42
|
+
end
|
79
43
|
|
80
44
|
context "when the step is enqueued" do
|
81
45
|
before { step.stub(:enqueued?).and_return(true) }
|
@@ -84,14 +48,14 @@ describe Massive::Process do
|
|
84
48
|
end
|
85
49
|
|
86
50
|
context "when the step is not enqueued" do
|
51
|
+
before { step.stub(:enqueued?).and_return(false) }
|
52
|
+
|
87
53
|
its(:next_step) { should eq step }
|
88
54
|
end
|
89
55
|
end
|
90
56
|
|
91
57
|
describe ".find_step" do
|
92
|
-
let!(:step) { process.steps.
|
93
|
-
|
94
|
-
before { process.save }
|
58
|
+
let!(:step) { process.steps.create }
|
95
59
|
|
96
60
|
it "returns the step with id within the process" do
|
97
61
|
Massive::Process.find_step(process.id, step.id).should eq(step)
|
@@ -99,10 +63,8 @@ describe Massive::Process do
|
|
99
63
|
end
|
100
64
|
|
101
65
|
describe ".find_job" do
|
102
|
-
let!(:step) { process.steps.
|
103
|
-
let!(:job) { step.jobs.
|
104
|
-
|
105
|
-
before { process.save }
|
66
|
+
let!(:step) { process.steps.create }
|
67
|
+
let!(:job) { step.jobs.create }
|
106
68
|
|
107
69
|
it "returns the job with id within the step of the process" do
|
108
70
|
Massive::Process.find_job(process.id, step.id, job.id).should eq(job)
|
@@ -110,8 +72,8 @@ describe Massive::Process do
|
|
110
72
|
end
|
111
73
|
|
112
74
|
describe "#processed_percentage" do
|
113
|
-
let(:step_1) { process.steps.
|
114
|
-
let(:step_2) { process.steps.
|
75
|
+
let(:step_1) { process.steps.create(weight: 9) }
|
76
|
+
let(:step_2) { process.steps.create }
|
115
77
|
|
116
78
|
context "when the process have not started" do
|
117
79
|
before do
|
@@ -162,19 +124,19 @@ describe Massive::Process do
|
|
162
124
|
end
|
163
125
|
|
164
126
|
context "when the total weight of the steps is zero" do
|
165
|
-
let(:step_1) { process.steps.
|
166
|
-
let(:step_2) { process.steps.
|
127
|
+
let(:step_1) { process.steps.create(weight: 0) }
|
128
|
+
let(:step_2) { process.steps.create(weight: 0) }
|
167
129
|
|
168
130
|
its(:processed_percentage) { should eq 0 }
|
169
131
|
end
|
170
132
|
end
|
171
133
|
|
172
134
|
describe "#completed?" do
|
173
|
-
let!(:step_1) { process.steps.build }
|
174
|
-
let!(:step_2) { process.steps.build }
|
175
|
-
|
176
135
|
before { process.save }
|
177
136
|
|
137
|
+
let!(:step_1) { process.steps.create }
|
138
|
+
let!(:step_2) { process.steps.create }
|
139
|
+
|
178
140
|
context "when the steps are incompleted steps" do
|
179
141
|
its(:completed?) { should be_false }
|
180
142
|
end
|
@@ -190,8 +152,8 @@ describe Massive::Process do
|
|
190
152
|
end
|
191
153
|
|
192
154
|
describe "#failed?" do
|
193
|
-
let!(:step_1) { process.steps.
|
194
|
-
let!(:step_2) { process.steps.
|
155
|
+
let!(:step_1) { process.steps.create }
|
156
|
+
let!(:step_2) { process.steps.create }
|
195
157
|
|
196
158
|
before { process.save }
|
197
159
|
|
@@ -7,6 +7,8 @@ describe Massive::Step do
|
|
7
7
|
let(:process) { Massive::Process.new }
|
8
8
|
subject(:step) { process.steps.build }
|
9
9
|
|
10
|
+
before { step.stub(:process).and_return(process) }
|
11
|
+
|
10
12
|
describe ".perform" do
|
11
13
|
before do
|
12
14
|
Massive::Process.stub(:find_step).with(process.id, step.id).and_return(step)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: massive
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vicente Mundim
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-04-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: resque
|
@@ -91,6 +91,7 @@ files:
|
|
91
91
|
- lib/massive/file.rb
|
92
92
|
- lib/massive/file_job.rb
|
93
93
|
- lib/massive/file_process.rb
|
94
|
+
- lib/massive/file_serializer.rb
|
94
95
|
- lib/massive/file_step.rb
|
95
96
|
- lib/massive/job.rb
|
96
97
|
- lib/massive/locking.rb
|
@@ -113,6 +114,7 @@ files:
|
|
113
114
|
- spec/models/massive/authenticators/s3_spec.rb
|
114
115
|
- spec/models/massive/cancelling_spec.rb
|
115
116
|
- spec/models/massive/file_job_spec.rb
|
117
|
+
- spec/models/massive/file_serializer_spec.rb
|
116
118
|
- spec/models/massive/file_spec.rb
|
117
119
|
- spec/models/massive/file_step_spec.rb
|
118
120
|
- spec/models/massive/job_spec.rb
|
@@ -160,6 +162,7 @@ test_files:
|
|
160
162
|
- spec/models/massive/authenticators/s3_spec.rb
|
161
163
|
- spec/models/massive/cancelling_spec.rb
|
162
164
|
- spec/models/massive/file_job_spec.rb
|
165
|
+
- spec/models/massive/file_serializer_spec.rb
|
163
166
|
- spec/models/massive/file_spec.rb
|
164
167
|
- spec/models/massive/file_step_spec.rb
|
165
168
|
- spec/models/massive/job_spec.rb
|