massive 0.3.0 → 0.4.0

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: 6add55169f9bbe782d2ee00b8a033a21aae4d9cb
4
- data.tar.gz: 3e7ef6017201515489a3e8f04fb41b8669b701cd
3
+ metadata.gz: d0ad236ec732665de7fcf03668e8ce4675da4344
4
+ data.tar.gz: acba7ff61e45ff129881fa0d86b49480eaa85912
5
5
  SHA512:
6
- metadata.gz: a2470c8e5230e4b2f4e12a47e93722e16da720971c15c67179aa8f053a1907c1322309f19fdef0572c43211d0b56f62a7d159d6a0c25422ab61cd339deab9a18
7
- data.tar.gz: 2e48d557a63fa84092f83acabca19ba70b3d21559bbb0f96f25dee3ee97c16b96e0daac07ccf26c40377046787184d8c5810ec1f00b9831ad54f100073a73b5f
6
+ metadata.gz: 1c922037b0dc37a497a6cced3880e88436912e6d3c8ff35ab8fc80c18f3375fbf4262551ea66ad82b7c5d065d0b20cb168c752400c28382df774027423687fe3
7
+ data.tar.gz: 122c02cc041df10b737ac8d6457d2bda985bb2930037672df0da4febe828648a9029829c08161597e9a5def1442e3f176062856fb15f52b7d4b72965f3d3c3b7
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- massive (0.3.0)
4
+ massive (0.4.0)
5
5
  active_model_serializers
6
6
  file_processor (= 0.2.0)
7
7
  mongoid (~> 4.0.0.beta)
@@ -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
@@ -0,0 +1,9 @@
1
+ module Massive
2
+ class FileSerializer < ActiveModel::Serializer
3
+ attributes :id, :url, :encoding, :col_sep, :total_count, :use_headers, :headers, :sample_data
4
+
5
+ def id
6
+ object.id.to_s
7
+ end
8
+ end
9
+ end
@@ -26,7 +26,26 @@ module Massive
26
26
  end
27
27
 
28
28
  def self.queue
29
- :massive_job
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
 
@@ -5,7 +5,7 @@ module Massive
5
5
 
6
6
  field :cancelled_at, type: Time
7
7
 
8
- embeds_many :steps, class_name: 'Massive::Step'
8
+ has_many :steps, class_name: 'Massive::Step', dependent: :destroy
9
9
 
10
10
  def self.find_step(process_id, step_id)
11
11
  find(process_id).steps.find(step_id)
@@ -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
@@ -9,7 +9,7 @@ module Massive
9
9
  include Massive::Locking
10
10
  include Massive::Notifications
11
11
 
12
- embedded_in :process, class_name: 'Massive::Process'
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
@@ -1,3 +1,3 @@
1
1
  module Massive
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -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.new }
4
+ subject(:process) { Massive::Process.create }
5
5
 
6
6
  describe "#enqueue_next" do
7
- context "when there are steps" do
8
- let!(:first_step) { process.steps.build }
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
- first_step.stub(:reload).and_return(first_step)
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
- context "and none of them are completed" do
19
- it "enqueues the first step" do
20
- first_step.should_receive(:enqueue)
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
- context "and the first one is completed, but the second one is not" do
32
- before { first_step.finished_at = Time.now }
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
- context "but all of them are completed" do
60
- before do
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
- end
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.build }
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.build }
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.build }
103
- let!(:job) { step.jobs.build }
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.build(weight: 9) }
114
- let(:step_2) { process.steps.build }
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.build(weight: 0) }
166
- let(:step_2) { process.steps.build(weight: 0) }
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.build }
194
- let!(:step_2) { process.steps.build }
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.3.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: 2014-05-15 00:00:00.000000000 Z
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