ts-resque-delta 1.1.5 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (30) hide show
  1. data/Gemfile +24 -0
  2. data/Guardfile +17 -0
  3. data/README.markdown +1 -0
  4. data/Rakefile +16 -4
  5. data/cucumber.yml +2 -0
  6. data/features/smart_indexing.feature +43 -0
  7. data/features/step_definitions/common_steps.rb +16 -3
  8. data/features/step_definitions/resque_delta_steps.rb +1 -1
  9. data/features/step_definitions/smart_indexing_steps.rb +3 -0
  10. data/features/support/env.rb +3 -4
  11. data/lib/thinking_sphinx/deltas/resque_delta.rb +32 -10
  12. data/lib/thinking_sphinx/deltas/resque_delta/core_index.rb +101 -0
  13. data/lib/thinking_sphinx/deltas/resque_delta/delta_job.rb +72 -10
  14. data/lib/thinking_sphinx/deltas/resque_delta/flag_as_deleted_set.rb +56 -0
  15. data/lib/thinking_sphinx/deltas/resque_delta/index_utils.rb +47 -0
  16. data/lib/thinking_sphinx/deltas/resque_delta/tasks.rb +4 -46
  17. data/lib/thinking_sphinx/deltas/resque_delta/version.rb +1 -1
  18. data/spec/spec_helper.rb +9 -5
  19. data/spec/thinking_sphinx/deltas/resque_delta/core_index_spec.rb +210 -0
  20. data/spec/thinking_sphinx/deltas/resque_delta/delta_job_spec.rb +138 -35
  21. data/spec/thinking_sphinx/deltas/resque_delta/flag_as_deleted_set_spec.rb +126 -0
  22. data/spec/thinking_sphinx/deltas/resque_delta/index_utils_spec.rb +67 -0
  23. data/spec/thinking_sphinx/deltas/resque_delta_spec.rb +126 -53
  24. data/ts-resque-delta.gemspec +8 -2
  25. metadata +185 -180
  26. data/features/support/redis_test_setup.rb +0 -23
  27. data/lib/thinking_sphinx/deltas/resque_delta/flag_as_deleted_job.rb +0 -30
  28. data/spec/spec.opts +0 -1
  29. data/spec/thinking_sphinx/deltas/resque_delta/flag_as_deleted_job_spec.rb +0 -66
  30. data/tasks/testing.rb +0 -20
@@ -0,0 +1,56 @@
1
+ class ThinkingSphinx::Deltas::ResqueDelta < ThinkingSphinx::Deltas::DefaultDelta
2
+ module FlagAsDeletedSet
3
+ extend self
4
+
5
+ def set_name(core_name)
6
+ "#{ThinkingSphinx::Deltas::ResqueDelta.job_prefix}:flag.deleted:#{core_name}:set"
7
+ end
8
+
9
+ def temp_name(core_name)
10
+ "#{ThinkingSphinx::Deltas::ResqueDelta.job_prefix}:flag.deleted:#{core_name}:temp"
11
+ end
12
+
13
+ def processing_name(core_name)
14
+ "#{ThinkingSphinx::Deltas::ResqueDelta.job_prefix}:flag.deleted:#{core_name}:processing"
15
+ end
16
+
17
+ def add(core_name, document_id)
18
+ Resque.redis.sadd(set_name(core_name), document_id)
19
+ end
20
+
21
+ def clear!(core_name)
22
+ Resque.redis.del(set_name(core_name))
23
+
24
+ #Clear processing set as well
25
+ delta_name = ThinkingSphinx::Deltas::ResqueDelta::IndexUtils.core_to_delta(core_name)
26
+ ThinkingSphinx::Deltas::ResqueDelta::DeltaJob.around_perform_lock(delta_name) do
27
+ Resque.redis.del(processing_name(core_name))
28
+ end
29
+ end
30
+
31
+ def clear_all!
32
+ ThinkingSphinx::Deltas::ResqueDelta::IndexUtils.core_indices.each do |core_index|
33
+ clear!(core_index)
34
+ end
35
+ end
36
+
37
+ def get_subset_for_processing(core_name)
38
+ # Copy set to temp
39
+ Resque.redis.sunionstore temp_name(core_name), set_name(core_name)
40
+ # Store (set - temp) into set. This removes all items we copied into temp from set.
41
+ Resque.redis.sdiffstore set_name(core_name), set_name(core_name), temp_name(core_name)
42
+ # Merge processing and temp together and store into processing.
43
+ Resque.redis.sunionstore processing_name(core_name), processing_name(core_name), temp_name(core_name)
44
+
45
+ Resque.redis.del temp_name(core_name)
46
+ end
47
+
48
+ def processing_members(core_name)
49
+ Resque.redis.smembers(processing_name(core_name)).collect(&:to_i)
50
+ end
51
+
52
+ def clear_processing(core_name)
53
+ Resque.redis.del(processing_name(core_name))
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,47 @@
1
+ module ThinkingSphinx::Deltas::ResqueDelta::IndexUtils
2
+ extend self
3
+
4
+ # Public: Return a list of index prefixes (i.e. without "_core"/"_delta").
5
+ #
6
+ # Examples
7
+ #
8
+ # sphinx_indices
9
+ # # => ['foo', 'bar']
10
+ #
11
+ # Returns an Array of index prefixes.
12
+ def index_prefixes
13
+ @prefixes ||= indices.reject { |i| i =~ /_(core|delta)$/ }
14
+ end
15
+
16
+ def core_indices
17
+ @core_indices ||= indices.select { |i| i =~ /_core$/ }
18
+ end
19
+
20
+ def delta_indices
21
+ @delta_indices ||= indices.select { |i| i =~ /_delta$/ }
22
+ end
23
+
24
+ def reload!
25
+ @ts_config = @indices = @prefixes = @core_indices = @delta_indices = nil
26
+ end
27
+
28
+ def delta_to_core(delta_name)
29
+ delta_name.sub(/_delta$/, '_core')
30
+ end
31
+
32
+ def core_to_delta(core_name)
33
+ core_name.sub(/_core$/, '_delta')
34
+ end
35
+
36
+ def ts_config
37
+ @ts_config ||= ThinkingSphinx::Configuration.instance.tap do |config|
38
+ config.generate
39
+ end
40
+ end
41
+
42
+ private
43
+ def indices
44
+ @indices ||= ts_config.configuration.indices.collect { |i| i.name }
45
+ end
46
+
47
+ end
@@ -1,67 +1,25 @@
1
1
  require 'thinking_sphinx/deltas/resque_delta'
2
2
 
3
3
  namespace :thinking_sphinx do
4
-
5
- # Return a list of index prefixes (i.e. without "_core"/"_delta").
6
- def sphinx_indices
7
- unless @sphinx_indices
8
- @ts_config ||= ThinkingSphinx::Configuration.instance
9
- @ts_config.generate
10
- @sphinx_indices = @ts_config.configuration.indices.collect { |i| i.name }
11
- # The collected indices look like:
12
- # ["foo_core", "foo_delta", "foo", "bar_core", "bar_delta", "bar"]
13
- @sphinx_indices.reject! { |i| i =~ /_(core|delta)$/}
14
- # Now we have:
15
- # ["foo", "bar"]
16
- end
17
- @sphinx_indices
18
- end
19
-
20
- def lock_delta(index_name)
21
- ThinkingSphinx::Deltas::ResqueDelta.lock("#{index_name}_delta")
22
- end
23
-
24
- def unlock_delta(index_name)
25
- ThinkingSphinx::Deltas::ResqueDelta.unlock("#{index_name}_delta")
26
- end
27
-
28
4
  desc 'Lock all delta indices (Resque will not run indexer or place new jobs on the :ts_delta queue).'
29
5
  task :lock_deltas do
30
- sphinx_indices.each { |index_name| lock_delta(index_name) }
6
+ ThinkingSphinx::Deltas::ResqueDelta::CoreIndex.new.lock_deltas
31
7
  end
32
8
 
33
9
  desc 'Unlock all delta indices.'
34
10
  task :unlock_deltas do
35
- sphinx_indices.each { |index_name| unlock_delta(index_name) }
11
+ ThinkingSphinx::Deltas::ResqueDelta::CoreIndex.new.unlock_deltas
36
12
  end
37
13
 
38
14
  desc 'Like `rake thinking_sphinx:index`, but locks one index at a time.'
39
15
  task :smart_index => :app_env do
40
- # Load config like ts:in.
41
- @ts_config = ThinkingSphinx::Configuration.instance
42
- unless ENV['INDEX_ONLY'] == 'true'
43
- puts "Generating Configuration to #{@ts_config.config_file}"
44
- @ts_config.build
45
- end
46
- FileUtils.mkdir_p(@ts_config.searchd_file_path)
16
+ ret = ThinkingSphinx::Deltas::ResqueDelta::CoreIndex.new.smart_index
47
17
 
48
- # Index each core, one at a time. Wrap with delta locking logic.
49
- sphinx_indices.each do |index_name|
50
- lock_delta(index_name)
51
- @ts_config.controller.index("#{index_name}_core", :verbose => true)
52
- ret = $?
53
- unlock_delta(index_name)
54
- exit(-1) if ret.to_i != 0
55
- Resque.enqueue(
56
- ThinkingSphinx::Deltas::ResqueDelta::DeltaJob,
57
- ["#{index_name}_delta"]
58
- )
59
- end
18
+ abort("Indexing failed.") if ret != true
60
19
  end
61
20
  end
62
21
 
63
22
  namespace :ts do
64
-
65
23
  desc 'Like `rake thinking_sphinx:index`, but locks one index at a time.'
66
24
  task :si => 'thinking_sphinx:smart_index'
67
25
  end
@@ -1,7 +1,7 @@
1
1
  module ThinkingSphinx
2
2
  module Deltas
3
3
  class ResqueDeltaInfo
4
- VERSION = "1.1.5"
4
+ VERSION = '1.2.0'
5
5
  end
6
6
  end
7
7
  end
data/spec/spec_helper.rb CHANGED
@@ -1,9 +1,13 @@
1
- $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
2
-
3
- require 'spec'
4
- require 'spec/autorun'
5
-
6
1
  require 'thinking_sphinx'
7
2
  require 'thinking_sphinx/deltas/resque_delta'
8
3
  require 'flying_sphinx'
9
4
  require 'flying_sphinx/resque_delta'
5
+
6
+ require 'mock_redis'
7
+ require 'fakefs/spec_helpers'
8
+
9
+ RSpec.configure do |c|
10
+ c.filter_run :focus => true
11
+ c.run_all_when_everything_filtered = true
12
+ c.treat_symbols_as_metadata_keys_with_true_values = true
13
+ end
@@ -0,0 +1,210 @@
1
+ require 'spec_helper'
2
+
3
+ describe ThinkingSphinx::Deltas::ResqueDelta::CoreIndex do
4
+ let(:indices) { %w[foo bar] }
5
+ let(:config) { double('config') }
6
+
7
+ describe '#lock_delta' do
8
+ it 'should lock the delta' do
9
+ ThinkingSphinx::Deltas::ResqueDelta.should_receive(:lock)
10
+
11
+ subject.lock_delta('foo')
12
+ end
13
+
14
+ it 'should lock the delta for the given index' do
15
+ ThinkingSphinx::Deltas::ResqueDelta.should_receive(:lock).with('foo_delta')
16
+
17
+ subject.lock_delta('foo')
18
+ end
19
+ end
20
+
21
+ describe '#unlock_delta' do
22
+ it 'should unlock the delta' do
23
+ ThinkingSphinx::Deltas::ResqueDelta.should_receive(:unlock)
24
+
25
+ subject.unlock_delta('foo')
26
+ end
27
+
28
+ it 'should unlock the delta for the given index' do
29
+ ThinkingSphinx::Deltas::ResqueDelta.should_receive(:unlock).with('foo_delta')
30
+
31
+ subject.unlock_delta('foo')
32
+ end
33
+ end
34
+
35
+ describe '#lock_deltas' do
36
+ it 'should lock all delta indices' do
37
+ subject.stub(:sphinx_indices => indices)
38
+
39
+ indices.each {|index| subject.should_receive(:lock_delta).once.with(index) }
40
+
41
+ subject.lock_deltas
42
+ end
43
+ end
44
+
45
+ describe '#unlock_deltas' do
46
+ it 'should unlock all delta indices' do
47
+ subject.stub(:sphinx_indices => indices)
48
+
49
+ indices.each {|index| subject.should_receive(:unlock_delta).once.with(index) }
50
+
51
+ subject.unlock_deltas
52
+ end
53
+ end
54
+
55
+ describe '#with_delta_index_lock' do
56
+ before :each do
57
+ subject.stub(:lock_delta)
58
+ subject.stub(:unlock_delta)
59
+
60
+ subject.stub(:block_called)
61
+
62
+ @block_called = false
63
+ @block = lambda { @block_called = true; subject.block_called }
64
+ end
65
+
66
+ it 'should yield' do
67
+ subject.with_delta_index_lock('foo', &@block)
68
+ @block_called.should be_true
69
+ end
70
+
71
+ it 'should lock before yielding' do
72
+ subject.should_receive(:lock_delta).with('foo').ordered
73
+ subject.should_receive(:block_called).ordered
74
+
75
+ subject.with_delta_index_lock('foo', &@block)
76
+ end
77
+
78
+ it 'should unlock after yielding' do
79
+ subject.should_receive(:block_called).ordered
80
+ subject.should_receive(:unlock_delta).with('foo').ordered
81
+
82
+ subject.with_delta_index_lock('foo', &@block)
83
+ end
84
+ end
85
+
86
+ describe '#smart_index' do
87
+ include FakeFS::SpecHelpers
88
+
89
+ let(:test_path) { '/tmp/ts-resque-delta/foo' }
90
+
91
+ before :each do
92
+ subject.stub(:ts_config => config)
93
+ config.stub(:config_file => 'foo_config')
94
+ config.stub(:build)
95
+ config.stub(:searchd_file_path => test_path)
96
+ config.stub_chain(:controller, :index) do
97
+ # Set $? to 0
98
+ `/usr/bin/true`
99
+ end
100
+
101
+ # Silence Generating config message
102
+ subject.stub(:puts)
103
+
104
+ subject.stub(:index_prefixes => indices)
105
+ subject.stub(:lock_delta)
106
+ subject.stub(:unlock_delta)
107
+
108
+ ThinkingSphinx::Deltas::ResqueDelta.stub(:prepare_for_core_index)
109
+ Resque.stub(:enqueue)
110
+ end
111
+
112
+ it 'should not generate sphinx configuration if INDEX_ONLY is true' do
113
+ ENV.stub(:[]).with('INDEX_ONLY').and_return('true')
114
+ ENV.stub(:[]).with('SILENT').and_return(nil)
115
+ config.should_not_receive(:build)
116
+
117
+ subject.smart_index
118
+ end
119
+
120
+ it 'should generate sphinx configuration if INDEX_ONLY is not true' do
121
+ ENV.stub(:[]).with('INDEX_ONLY').and_return(nil)
122
+ ENV.stub(:[]).with('SILENT').and_return(nil)
123
+ config.should_receive(:build).once
124
+
125
+ subject.smart_index
126
+ end
127
+
128
+ it 'should create the sphinx file directory' do
129
+ subject.smart_index
130
+
131
+ File.directory?(test_path).should be_true
132
+ end
133
+
134
+ it 'should index all core indices' do
135
+ indices.each do |index|
136
+ config.controller.should_receive(:index).with("#{index}_core", anything)
137
+ end
138
+
139
+ subject.smart_index
140
+ end
141
+
142
+ context "with delta lock" do
143
+ before :each do
144
+ subject.stub(:with_delta_index_lock).and_yield
145
+ end
146
+
147
+ it 'should index' do
148
+ config.controller.should_receive(:index)
149
+ subject.smart_index
150
+ end
151
+
152
+ it 'should signal resque delta to prepare for the core index' do
153
+ ThinkingSphinx::Deltas::ResqueDelta.should_receive(:prepare_for_core_index)
154
+ subject.smart_index
155
+ end
156
+ end
157
+
158
+ context "without delta lock" do
159
+ before :each do
160
+ subject.stub(:with_delta_index_lock)
161
+ end
162
+
163
+ it 'should not index without the delta lock' do
164
+ config.controller.should_not_receive(:index)
165
+ subject.smart_index
166
+ end
167
+
168
+ it 'should not signal resque delta to prepare for the core index' do
169
+ ThinkingSphinx::Deltas::ResqueDelta.should_not_receive(:prepare_for_core_index)
170
+ subject.smart_index
171
+ end
172
+ end
173
+
174
+ it 'should create a delta job after the delta is unlocked' do
175
+ # Create a dummy method on subject that's called when Resque.enqueue is called so we can enforce order.
176
+ subject.stub(:resque_called)
177
+ Resque.stub(:enqueue) { subject.resque_called }
178
+
179
+ Resque.should_receive(:enqueue)
180
+
181
+ subject.should_receive(:with_delta_index_lock).ordered.exactly(indices.size)
182
+ subject.should_receive(:resque_called).ordered.exactly(indices.size)
183
+
184
+ subject.smart_index
185
+ end
186
+
187
+ context 'with an error' do
188
+ before :each do
189
+ config.stub_chain(:controller, :index) do
190
+ # Set $? to 1
191
+ `/usr/bin/false`
192
+ end
193
+ end
194
+
195
+ it 'should stop processing indexes after an error' do
196
+ config.controller.should_receive(:index).once
197
+
198
+ subject.smart_index
199
+ end
200
+
201
+ it 'should return false on failure' do
202
+ subject.smart_index.should be_false
203
+ end
204
+ end
205
+
206
+ it 'should return true on success' do
207
+ subject.smart_index.should be_true
208
+ end
209
+ end
210
+ end
@@ -1,48 +1,37 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe ThinkingSphinx::Deltas::ResqueDelta::DeltaJob do
4
+ subject do
5
+ ThinkingSphinx::Deltas::ResqueDelta::DeltaJob.tap do |s|
6
+ s.stub(:` => true)
7
+ s.stub(:puts => nil)
8
+ end
9
+ end
10
+
4
11
  describe '.perform' do
5
12
  before :each do
6
13
  ThinkingSphinx.suppress_delta_output = false
7
- ThinkingSphinx::Deltas::ResqueDelta::DeltaJob.stub(:` => true)
8
- ThinkingSphinx::Deltas::ResqueDelta::DeltaJob.stub(:puts => nil)
9
14
  ThinkingSphinx::Deltas::ResqueDelta.stub(:locked?).and_return(false)
15
+ ThinkingSphinx.stub(:sphinx_running? => false)
10
16
  end
11
17
 
12
18
  it "should output the delta indexing by default" do
13
- ThinkingSphinx::Deltas::ResqueDelta::DeltaJob.should_receive(:puts)
14
- ThinkingSphinx::Deltas::ResqueDelta::DeltaJob.perform(
15
- ['foo_delta']
16
- )
19
+ subject.should_receive(:puts)
20
+ subject.perform('foo_delta')
17
21
  end
18
22
 
19
23
  it "should not output the delta indexing if requested" do
20
24
  ThinkingSphinx.suppress_delta_output = true
21
- ThinkingSphinx::Deltas::ResqueDelta::DeltaJob.should_not_receive(:puts)
22
- ThinkingSphinx::Deltas::ResqueDelta::DeltaJob.perform(
23
- ['foo_delta']
24
- )
25
+ subject.should_not_receive(:puts)
26
+ subject.perform('foo_delta')
25
27
  end
26
28
 
27
- it "should process just the requested indices" do
28
- ThinkingSphinx::Deltas::ResqueDelta::DeltaJob.should_receive(:`) do |c|
29
+ it "should process just the requested index" do
30
+ subject.should_receive(:`) do |c|
29
31
  c.should match(/foo_delta/)
30
32
  c.should_not match(/--all/)
31
33
  end
32
- ThinkingSphinx::Deltas::ResqueDelta::DeltaJob.perform(
33
- ['foo_delta']
34
- )
35
- end
36
-
37
- context 'multiple indices' do
38
- it "should process all requested indices" do
39
- ThinkingSphinx::Deltas::ResqueDelta::DeltaJob.should_receive(:`) do |c|
40
- c.should match(/foo_delta bar_delta/)
41
- end
42
- ThinkingSphinx::Deltas::ResqueDelta::DeltaJob.perform(
43
- ['foo_delta', 'bar_delta']
44
- )
45
- end
34
+ subject.perform('foo_delta')
46
35
  end
47
36
 
48
37
  context 'when an index is locked' do
@@ -53,18 +42,132 @@ describe ThinkingSphinx::Deltas::ResqueDelta::DeltaJob do
53
42
  end
54
43
 
55
44
  it "should not start the indexer" do
56
- ThinkingSphinx::Deltas::ResqueDelta::DeltaJob.should_not_receive(:`)
57
- ThinkingSphinx::Deltas::ResqueDelta::DeltaJob.perform(
58
- ['foo_delta']
59
- )
45
+ subject.should_not_receive(:`)
46
+ subject.perform('foo_delta')
47
+ end
48
+
49
+ it "should start the indexer for unlocked indexes" do
50
+ subject.should_receive(:`)
51
+ subject.perform('bar_delta')
52
+ end
53
+ end
54
+
55
+ context 'with flag as deleted document ids' do
56
+ let(:client) { stub('client', :update => true) }
57
+ let(:document_ids) { [1, 2, 3] }
58
+
59
+ before :each do
60
+ ThinkingSphinx.updates_enabled = true
61
+
62
+ ThinkingSphinx::Configuration.instance.stub(:client => client)
63
+ ThinkingSphinx.stub(:sphinx_running? => true)
64
+
65
+ ThinkingSphinx::Deltas::ResqueDelta::FlagAsDeletedSet.stub(:processing_members => document_ids)
66
+ subject.stub(:filter_flag_as_deleted_ids => document_ids)
60
67
  end
61
68
 
62
- it "should not start the indexer for multiple indices" do
63
- ThinkingSphinx::Deltas::ResqueDelta::DeltaJob.should_not_receive(:`)
64
- ThinkingSphinx::Deltas::ResqueDelta::DeltaJob.perform(
65
- ['bar_delta', 'foo_delta']
66
- )
69
+ it 'should get the processing set of flag as deleted document ids' do
70
+ ThinkingSphinx::Deltas::ResqueDelta::FlagAsDeletedSet.should_receive(:processing_members).with('foo_core')
71
+ subject.perform('foo_delta')
67
72
  end
73
+
74
+ it "should not update if Sphinx isn't running" do
75
+ ThinkingSphinx.stub(:sphinx_running? => false)
76
+ client.should_not_receive(:update)
77
+ subject.perform('foo_delta')
78
+ end
79
+
80
+ it "should validate the document ids with sphinx" do
81
+ subject.should_receive(:filter_flag_as_deleted_ids).with(document_ids, 'foo_core')
82
+
83
+ subject.perform('foo_delta')
84
+ end
85
+
86
+ context "with invalid ids" do
87
+ before :each do
88
+ subject.stub(:filter_flag_as_deleted_ids => document_ids.reject {|x| x == 2} )
89
+ end
90
+
91
+ it "should not update documents that aren't in the index" do
92
+ client.should_receive(:update) do |index, attributes, values|
93
+ values.should_not include(2)
94
+ end
95
+ subject.perform('foo_delta')
96
+ end
97
+
98
+ it "should update documents that are in the index" do
99
+ client.should_receive(:update) do |index, attributes, values|
100
+ values.keys.should eql(document_ids.reject{|x| x == 2})
101
+ end
102
+ subject.perform('foo_delta')
103
+ end
104
+ end
105
+
106
+ it "should update the specified index" do
107
+ client.should_receive(:update) do |index, attributes, values|
108
+ index.should == 'foo_core'
109
+ end
110
+ subject.perform('foo_delta')
111
+ end
112
+
113
+ it "should update the sphinx_deleted attribute" do
114
+ client.should_receive(:update) do |index, attributes, values|
115
+ attributes.should == ['sphinx_deleted']
116
+ end
117
+ subject.perform('foo_delta')
118
+ end
119
+
120
+ it "should set sphinx_deleted for valid documents to true" do
121
+ client.should_receive(:update) do |index, attributes, values|
122
+ document_ids.each {|id| values[id].should == [1] }
123
+ end
124
+ subject.perform('foo_delta')
125
+ end
126
+
127
+ context "without any ids" do
128
+ let(:document_ids) { [] }
129
+
130
+ it "should not validate the ids with sphinx" do
131
+ subject.should_not_receive(:filter_flag_as_deleted_ids)
132
+ subject.perform('foo_delta')
133
+ end
134
+ end
135
+ end
136
+ end
137
+
138
+ describe '.around_perform_lock1' do
139
+ before :each do
140
+ Resque.stub(:encode => 'DeltaJobsAreAwesome')
141
+ Resque.stub_chain(:redis, :lrem)
142
+ ThinkingSphinx::Deltas::ResqueDelta::FlagAsDeletedSet.stub(:get_subset_for_processing)
143
+ ThinkingSphinx::Deltas::ResqueDelta::FlagAsDeletedSet.stub(:clear_processing)
144
+ end
145
+
146
+ it 'should clear all other delta jobs' do
147
+ Resque.redis.should_receive(:lrem).with("queue:#{subject.instance_variable_get(:@queue)}", 0, 'DeltaJobsAreAwesome')
148
+
149
+ subject.around_perform_lock1('foo_delta') {}
150
+ end
151
+
152
+ it 'should set up the processing set of document ids' do
153
+ ThinkingSphinx::Deltas::ResqueDelta::FlagAsDeletedSet.should_receive(:get_subset_for_processing).with('foo_core')
154
+
155
+ subject.around_perform_lock1('foo_delta') {}
156
+ end
157
+
158
+ it 'should clear the processing set when finished' do
159
+ ThinkingSphinx::Deltas::ResqueDelta::FlagAsDeletedSet.should_receive(:clear_processing).with('foo_core')
160
+
161
+ subject.around_perform_lock1('foo_delta') {}
162
+ end
163
+ end
164
+
165
+ describe '.lock_failed' do
166
+ it 'should enqueue the delta job again' do
167
+ Resque.stub(:enqueue => true)
168
+ Resque.should_receive(:enqueue)
169
+
170
+ subject.lock_failed('foo_delta')
68
171
  end
69
172
  end
70
173
  end