namxam-ts-delayed-delta 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Pat Allan
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,54 @@
1
+ h1. Delayed Deltas for Thinking Sphinx
2
+
3
+ h2. Installation
4
+
5
+ You'll need Thinking Sphinx 1.3.0 or later, and Delayed Job as well. The latter is flagged as a dependency.
6
+
7
+ <pre><code>gem install ts-delayed-delta --source http://gemcutter.org</code></pre>
8
+
9
+ In your @environment.rb@ file, with the rest of your gem dependencies:
10
+
11
+ <pre><code>config.gem 'ts-delayed-delta',
12
+ :lib => 'thinking_sphinx/deltas/delayed_delta'
13
+ :version => '>= 1.0.0',
14
+ :source => 'http://gemcutter.org'</code></pre>
15
+
16
+ And add the following line to the bottom of your @Rakefile@:
17
+
18
+ <pre><code>require 'thinking_sphinx/deltas/delayed_delta/tasks'</code></pre>
19
+
20
+ If this is your first time running Delayed Job, then you're going to need the jobs table migration as well:
21
+
22
+ <pre><code>script/generate delayed_job</code></pre>
23
+
24
+ For the indexes you want to use this delta approach, make sure you set that up in their @define_index@ blocks.
25
+
26
+ <pre><code>define_index do
27
+ # ...
28
+
29
+ set_property :delta => :delayed
30
+ end</code></pre>
31
+
32
+ If you've never used delta indexes before, you'll want to add the boolean column named delta to each model that is using the approach.
33
+
34
+ <pre><code>def self.up
35
+ add_column :articles, :delta, :boolean, :default => true, :null => false
36
+ end</code></pre>
37
+
38
+ h2. Usage
39
+
40
+ Once you've got it all set up, all you need to do is make sure that the delayed job process is running - either by Delayed Job's built-in approach, or Thinking Sphinx's custom rake task:
41
+
42
+ <pre><code>rake thinking_sphinx:delayed_delta</code></pre>
43
+
44
+ There's also a short name for the same task, to save your fingers some effort:
45
+
46
+ <pre><code>rake ts:dd</code></pre>
47
+
48
+ h2. Contributors
49
+
50
+ * "Ryan Schlesinger":http://github.com/ryansch
51
+
52
+ h2. Copyright
53
+
54
+ Copyright (c) 2009 Pat Allan, and released under an MIT Licence.
@@ -0,0 +1,37 @@
1
+ Feature: Delayed Delta Indexing
2
+ In order to have delta indexing on frequently-updated sites
3
+ Developers
4
+ Should be able to use delayed_job to handle delta indexes to lower system load
5
+
6
+ Scenario: Delta Index should not fire automatically
7
+ Given Sphinx is running
8
+ And I am searching on delayed betas
9
+ When I search for one
10
+ Then I should get 1 result
11
+
12
+ When I change the name of delayed beta one to eleven
13
+ And I wait for Sphinx to catch up
14
+ And I search for one
15
+ Then I should get 1 result
16
+
17
+ When I search for eleven
18
+ Then I should get 0 results
19
+
20
+ Scenario: Delta Index should fire when jobs are run
21
+ Given Sphinx is running
22
+ And I am searching on delayed betas
23
+ When I search for one
24
+ Then I should get 1 result
25
+
26
+ When I change the name of delayed beta two to twelve
27
+ And I wait for Sphinx to catch up
28
+ And I search for twelve
29
+ Then I should get 0 results
30
+
31
+ When I run the delayed jobs
32
+ And I wait for Sphinx to catch up
33
+ And I search for twelve
34
+ Then I should get 1 result
35
+
36
+ When I search for two
37
+ Then I should get 0 results
@@ -0,0 +1,48 @@
1
+ Before do
2
+ $queries_executed = []
3
+ ThinkingSphinx::Deltas::Job.cancel_thinking_sphinx_jobs
4
+
5
+ @model = nil
6
+ @method = :search
7
+ @query = ""
8
+ @conditions = {}
9
+ @with = {}
10
+ @without = {}
11
+ @with_all = {}
12
+ @options = {}
13
+ @results = nil
14
+ end
15
+
16
+ Given "Sphinx is running" do
17
+ ThinkingSphinx::Configuration.instance.controller.should be_running
18
+ end
19
+
20
+ Given /^I am searching on (.+)$/ do |model|
21
+ @model = model.gsub(/\s/, '_').singularize.camelize.constantize
22
+ end
23
+
24
+ When "I wait for Sphinx to catch up" do
25
+ sleep(0.25)
26
+ end
27
+
28
+ When /^I search for (\w+)$/ do |query|
29
+ @results = nil
30
+ @query = query
31
+ end
32
+
33
+ Then /^I should get (\d+) results?$/ do |count|
34
+ results.length.should == count.to_i
35
+ end
36
+
37
+ def results
38
+ @results ||= (@model || ThinkingSphinx).send(
39
+ @method,
40
+ @query,
41
+ @options.merge(
42
+ :conditions => @conditions,
43
+ :with => @with,
44
+ :without => @without,
45
+ :with_all => @with_all
46
+ )
47
+ )
48
+ end
@@ -0,0 +1,7 @@
1
+ When /^I run the delayed jobs$/ do
2
+ Delayed::Job.work_off.inspect
3
+ end
4
+
5
+ When /^I change the name of delayed beta (\w+) to (\w+)$/ do |current, replacement|
6
+ DelayedBeta.find_by_name(current).update_attributes(:name => replacement)
7
+ end
@@ -0,0 +1,3 @@
1
+ username: root
2
+ host: localhost
3
+ password:
@@ -0,0 +1,10 @@
1
+ DelayedBeta.create :name => "one"
2
+ DelayedBeta.create :name => "two"
3
+ DelayedBeta.create :name => "three"
4
+ DelayedBeta.create :name => "four"
5
+ DelayedBeta.create :name => "five"
6
+ DelayedBeta.create :name => "six"
7
+ DelayedBeta.create :name => "seven"
8
+ DelayedBeta.create :name => "eight"
9
+ DelayedBeta.create :name => "nine"
10
+ DelayedBeta.create :name => "ten"
@@ -0,0 +1,17 @@
1
+ ActiveRecord::Base.connection.create_table :delayed_betas, :force => true do |t|
2
+ t.column :name, :string, :null => false
3
+ t.column :delta, :boolean, :null => false, :default => false
4
+ end
5
+
6
+ ActiveRecord::Base.connection.create_table :delayed_jobs, :force => true do |t|
7
+ t.column :priority, :integer, :default => 0
8
+ t.column :attempts, :integer, :default => 0
9
+ t.column :handler, :text
10
+ t.column :last_error, :string
11
+ t.column :run_at, :datetime
12
+ t.column :locked_at, :datetime
13
+ t.column :failed_at, :datetime
14
+ t.column :locked_by, :string
15
+ t.column :created_at, :datetime
16
+ t.column :updated_at, :datetime
17
+ end
@@ -0,0 +1,17 @@
1
+ require 'rubygems'
2
+ require 'cucumber'
3
+ require 'spec/expectations'
4
+ require 'fileutils'
5
+ require 'active_record'
6
+
7
+ $:.unshift File.dirname(__FILE__) + '/../../lib'
8
+
9
+ require 'cucumber/thinking_sphinx/internal_world'
10
+
11
+ world = Cucumber::ThinkingSphinx::InternalWorld.new
12
+ world.configure_database
13
+
14
+ require "thinking_sphinx"
15
+ require 'thinking_sphinx/deltas/delayed_delta'
16
+
17
+ world.setup
@@ -0,0 +1,7 @@
1
+ class DelayedBeta < ActiveRecord::Base
2
+ define_index do
3
+ indexes :name, :sortable => true
4
+
5
+ set_property :delta => :delayed
6
+ end
7
+ end
@@ -0,0 +1,64 @@
1
+ require 'delayed_job'
2
+ require 'thinking_sphinx'
3
+ require 'thinking_sphinx/deltas/delayed_delta/delta_job'
4
+ require 'thinking_sphinx/deltas/delayed_delta/flag_as_deleted_job'
5
+ require 'thinking_sphinx/deltas/delayed_delta/job'
6
+
7
+ # Delayed Deltas for Thinking Sphinx, using Delayed Job.
8
+ #
9
+ # This documentation is aimed at those reading the code. If you're looking for
10
+ # a guide to Thinking Sphinx and/or deltas, I recommend you start with the
11
+ # Thinking Sphinx site instead - or the README for this library at the very
12
+ # least.
13
+ #
14
+ # @author Patrick Allan
15
+ # @see http://ts.freelancing-gods.com Thinking Sphinx
16
+ #
17
+ class ThinkingSphinx::Deltas::DelayedDelta < ThinkingSphinx::Deltas::DefaultDelta
18
+
19
+ # Adds a job to the queue for processing the given model's delta index. A job
20
+ # for hiding the instance in the core index is also created, if an instance is
21
+ # provided.
22
+ #
23
+ # Neither job will be queued if updates or deltas are disabled, or if the
24
+ # instance (when given) is not toggled to be in the delta index. The first two
25
+ # options are controlled via ThinkingSphinx.updates_enabled? and
26
+ # ThinkingSphinx.deltas_enabled?.
27
+ #
28
+ # @param [Class] model the ActiveRecord model to index.
29
+ # @param [ActiveRecord::Base] instance the instance of the given model that
30
+ # has changed. Optional.
31
+ # @return [Boolean] true
32
+ #
33
+ def index(model, instance = nil)
34
+ return true if skip? instance
35
+
36
+ ThinkingSphinx::Deltas::Job.enqueue(
37
+ ThinkingSphinx::Deltas::DeltaJob.new(model.delta_index_names),
38
+ ThinkingSphinx::Configuration.instance.delayed_job_priority
39
+ )
40
+
41
+ Delayed::Job.enqueue(
42
+ ThinkingSphinx::Deltas::FlagAsDeletedJob.new(
43
+ model.core_index_names, instance.sphinx_document_id
44
+ ),
45
+ ThinkingSphinx::Configuration.instance.delayed_job_priority
46
+ ) if instance
47
+
48
+ true
49
+ end
50
+
51
+ private
52
+
53
+ # Checks whether jobs should be enqueued. Only true if updates and deltas are
54
+ # enabled, and the instance (if there is one) is toggled.
55
+ #
56
+ # @param [ActiveRecord::Base, NilClass] instance
57
+ # @return [Boolean]
58
+ #
59
+ def skip?(instance)
60
+ !ThinkingSphinx.updates_enabled? ||
61
+ !ThinkingSphinx.deltas_enabled? ||
62
+ (instance && !toggled(instance))
63
+ end
64
+ end
@@ -0,0 +1,27 @@
1
+ # A simple job class that processes a given index.
2
+ #
3
+ class ThinkingSphinx::Deltas::DeltaJob
4
+ attr_accessor :indexes
5
+
6
+ # Initialises the object with an index name.
7
+ #
8
+ # @param [String] index the name of the Sphinx index
9
+ #
10
+ def initialize(indexes)
11
+ @indexes = indexes
12
+ end
13
+
14
+ # Runs Sphinx's indexer tool to process the index. Currently assumes Sphinx is
15
+ # running.
16
+ #
17
+ # @return [Boolean] true
18
+ #
19
+ def perform
20
+ config = ThinkingSphinx::Configuration.instance
21
+
22
+ output = `#{config.bin_path}#{config.indexer_binary_name} --config #{config.config_file} --rotate #{indexes.join(' ')}`
23
+ puts output unless ThinkingSphinx.suppress_delta_output?
24
+
25
+ true
26
+ end
27
+ end
@@ -0,0 +1,40 @@
1
+ # A simple job for flagging a specified Sphinx document in a given index as
2
+ # 'deleted'.
3
+ #
4
+ class ThinkingSphinx::Deltas::FlagAsDeletedJob
5
+ attr_accessor :indexes, :document_id
6
+
7
+ # Initialises the object with an index name and document id. Please note that
8
+ # the document id is Sphinx's unique identifier, and will almost certainly not
9
+ # be the model instance's primary key value.
10
+ #
11
+ # @param [String] index The index name
12
+ # @param [Integer] document_id The document id
13
+ #
14
+ def initialize(indexes, document_id)
15
+ @indexes, @document_id = indexes, document_id
16
+ end
17
+
18
+ # Updates the sphinx_deleted attribute for the given document, setting the
19
+ # value to 1 (true). This is not a special attribute in Sphinx, but is used
20
+ # by Thinking Sphinx to ignore deleted values between full re-indexing. It's
21
+ # particularly useful in this situation to avoid old values in the core index
22
+ # and just use the new values in the delta index as a reference point.
23
+ #
24
+ # @return [Boolean] true
25
+ #
26
+ def perform
27
+ config = ThinkingSphinx::Configuration.instance
28
+
29
+ indexes.each do |index|
30
+ config.client.update(
31
+ index,
32
+ ['sphinx_deleted'],
33
+ {@document_id => [1]}
34
+ ) if ThinkingSphinx.sphinx_running? &&
35
+ ThinkingSphinx.search_for_id(@document_id, index)
36
+ end
37
+
38
+ true
39
+ end
40
+ end
@@ -0,0 +1,54 @@
1
+ # A custom job model, subclassed from Delayed::Job. The two things it does
2
+ # differently is that it checks for duplicate tasks before enqueuing them, and
3
+ # provides the option to remove all Delayed Delta jobs from the queue.
4
+ #
5
+ # As such, this class should not be used for any other tasks.
6
+ #
7
+ class ThinkingSphinx::Deltas::Job < Delayed::Job
8
+ # Adds a job to the queue, if it doesn't already exist. This is to ensure
9
+ # multiple indexing requests for the same delta index don't get added, as the
10
+ # index only needs to be processed once.
11
+ #
12
+ # Because indexing jobs are all the same object, with a single instance
13
+ # variable (the index name), they all get serialised to the same YAML value.
14
+ #
15
+ # @param [Object] object The job, which must respond to the #perform method.
16
+ # @param [Integer] priority (0)
17
+ #
18
+ def self.enqueue(object, priority = 0)
19
+ ::Delayed::Job.enqueue(object, priority) unless duplicates_exist(object)
20
+ end
21
+
22
+ # Remove all Thinking Sphinx/Delayed Delta jobs from the queue. If the
23
+ # delayed_jobs table does not exist, this method will do nothing.
24
+ #
25
+ def self.cancel_thinking_sphinx_jobs
26
+ if connection.tables.include?("delayed_jobs")
27
+ delete_all("handler LIKE '--- !ruby/object:ThinkingSphinx::Deltas::%'")
28
+ end
29
+ end
30
+
31
+ # This is to stop ActiveRecord complaining about a missing database when
32
+ # running specs (otherwise printing failure messages raises confusing stack
33
+ # traces).
34
+ #
35
+ def self.inspect
36
+ "Job"
37
+ end
38
+
39
+ private
40
+
41
+ # Checks whether a given job already exists in the queue.
42
+ #
43
+ # @param [Object] object The job
44
+ # @return [Boolean] True if a duplicate of the job already exists in the queue
45
+ #
46
+ def self.duplicates_exist(object)
47
+ count(
48
+ :conditions => {
49
+ :handler => object.to_yaml,
50
+ :locked_at => nil
51
+ }
52
+ ) > 0
53
+ end
54
+ end
@@ -0,0 +1,21 @@
1
+ namespace :thinking_sphinx do
2
+ task :index do
3
+ ThinkingSphinx::Deltas::Job.cancel_thinking_sphinx_jobs
4
+ end
5
+
6
+ desc "Process stored delta index requests"
7
+ task :delayed_delta => :app_env do
8
+ require 'delayed/worker'
9
+ require 'thinking_sphinx/deltas/delayed_delta'
10
+
11
+ Delayed::Worker.new(
12
+ :min_priority => ENV['MIN_PRIORITY'],
13
+ :max_priority => ENV['MAX_PRIORITY']
14
+ ).start
15
+ end
16
+ end
17
+
18
+ namespace :ts do
19
+ desc "Process stored delta index requests"
20
+ task :dd => "thinking_sphinx:delayed_delta"
21
+ end
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,12 @@
1
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
2
+
3
+ require 'rubygems'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+
7
+ require 'thinking_sphinx'
8
+ require 'thinking_sphinx/deltas/delayed_delta'
9
+
10
+ Spec::Runner.configure do |config|
11
+ #
12
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe ThinkingSphinx::Deltas::DeltaJob do
4
+ describe '#perform' do
5
+ before :each do
6
+ ThinkingSphinx.suppress_delta_output = false
7
+
8
+ @delta_job = ThinkingSphinx::Deltas::DeltaJob.new(['foo_core'])
9
+ @delta_job.stub! :` => true
10
+ @delta_job.stub! :puts => nil
11
+ end
12
+
13
+ it "should output the delta indexing by default" do
14
+ @delta_job.should_receive(:puts)
15
+
16
+ @delta_job.perform
17
+ end
18
+
19
+ it "should not output the delta indexing if requested" do
20
+ ThinkingSphinx.suppress_delta_output = true
21
+ @delta_job.should_not_receive(:puts)
22
+
23
+ @delta_job.perform
24
+ end
25
+
26
+ it "should process just the requested indexes" do
27
+ @delta_job.should_receive(:`) do |command|
28
+ command.should match(/foo_core/)
29
+ command.should_not match(/--all/)
30
+ end
31
+
32
+ @delta_job.perform
33
+ end
34
+
35
+ context 'multiple indexes' do
36
+ it "should process all requested indexes" do
37
+ @delta_job.indexes = ['foo_core', 'bar_core']
38
+ @delta_job.should_receive(:`) do |command|
39
+ command.should match(/foo_core bar_core/)
40
+ end
41
+
42
+ @delta_job.perform
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,78 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe ThinkingSphinx::Deltas::FlagAsDeletedJob do
4
+ describe '#perform' do
5
+ before :each do
6
+ ThinkingSphinx.updates_enabled = true
7
+ @client = stub('client', :update => true)
8
+
9
+ ThinkingSphinx::Configuration.instance.stub!(:client => @client)
10
+ ThinkingSphinx.stub!(:search_for_id => true)
11
+ ThinkingSphinx.stub!(:sphinx_running? => true)
12
+
13
+ @job = ThinkingSphinx::Deltas::FlagAsDeletedJob.new(['foo_core'], 12)
14
+ end
15
+
16
+ it "should not update if Sphinx isn't running" do
17
+ ThinkingSphinx.stub!(:sphinx_running? => false)
18
+ @client.should_not_receive(:update)
19
+
20
+ @job.perform
21
+ end
22
+
23
+ it "should not update if the document isn't in the index" do
24
+ ThinkingSphinx.stub!(:search_for_id => false)
25
+ @client.should_not_receive(:update)
26
+
27
+ @job.perform
28
+ end
29
+
30
+ it "should update the specified index" do
31
+ @client.should_receive(:update) do |index, attributes, values|
32
+ index.should == 'foo_core'
33
+ end
34
+
35
+ @job.perform
36
+ end
37
+
38
+ it "should update all specified indexes" do
39
+ @job.indexes = ['foo_core', 'bar_core']
40
+ @client.should_receive(:update).with('foo_core', anything, anything)
41
+ @client.should_receive(:update).with('bar_core', anything, anything)
42
+
43
+ @job.perform
44
+ end
45
+
46
+ it "should update the sphinx_deleted attribute" do
47
+ @client.should_receive(:update) do |index, attributes, values|
48
+ attributes.should == ['sphinx_deleted']
49
+ end
50
+
51
+ @job.perform
52
+ end
53
+
54
+ it "should set sphinx_deleted for the given document to true" do
55
+ @client.should_receive(:update) do |index, attributes, values|
56
+ values[12].should == [1]
57
+ end
58
+
59
+ @job.perform
60
+ end
61
+
62
+ it "should check for the existence of the document in the specified index" do
63
+ ThinkingSphinx.should_receive(:search_for_id) do |id, index|
64
+ index.should == 'foo_core'
65
+ end
66
+
67
+ @job.perform
68
+ end
69
+
70
+ it "should check for the existence of the given document id" do
71
+ ThinkingSphinx.should_receive(:search_for_id) do |id, index|
72
+ id.should == 12
73
+ end
74
+
75
+ @job.perform
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,52 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe ThinkingSphinx::Deltas::Job do
4
+ describe '.enqueue' do
5
+ before :each do
6
+ ThinkingSphinx::Deltas::Job.stub!(:count => 0)
7
+ end
8
+
9
+ it "should enqueue if there's no existing jobs for the same index" do
10
+ Delayed::Job.should_receive(:enqueue)
11
+
12
+ ThinkingSphinx::Deltas::Job.enqueue(stub('object'))
13
+ end
14
+
15
+ it "should not enqueue the job if there's an existing job already" do
16
+ ThinkingSphinx::Deltas::Job.stub!(:count => 1)
17
+ Delayed::Job.should_not_receive(:enqueue)
18
+
19
+ ThinkingSphinx::Deltas::Job.enqueue(stub('object'))
20
+ end
21
+ end
22
+
23
+ describe '.cancel_thinking_sphinx_jobs' do
24
+ before :each do
25
+ ThinkingSphinx::Deltas::Job.stub!(:connection, stub('connection'))
26
+ ThinkingSphinx::Deltas::Job.stub!(:delete_all => true)
27
+ end
28
+
29
+ it "should not delete any rows if the delayed_jobs table does not exist" do
30
+ ThinkingSphinx::Deltas::Job.connection.stub!(:tables => [])
31
+ ThinkingSphinx::Deltas::Job.should_not_receive(:delete_all)
32
+
33
+ ThinkingSphinx::Deltas::Job.cancel_thinking_sphinx_jobs
34
+ end
35
+
36
+ it "should delete rows if the delayed_jobs table does exist" do
37
+ ThinkingSphinx::Deltas::Job.connection.stub!(:tables => ['delayed_jobs'])
38
+ ThinkingSphinx::Deltas::Job.should_receive(:delete_all)
39
+
40
+ ThinkingSphinx::Deltas::Job.cancel_thinking_sphinx_jobs
41
+ end
42
+
43
+ it "should delete only Thinking Sphinx jobs" do
44
+ ThinkingSphinx::Deltas::Job.connection.stub!(:tables => ['delayed_jobs'])
45
+ ThinkingSphinx::Deltas::Job.should_receive(:delete_all) do |sql|
46
+ sql.should match(/handler LIKE '--- !ruby\/object:ThinkingSphinx::Deltas::\%'/)
47
+ end
48
+
49
+ ThinkingSphinx::Deltas::Job.cancel_thinking_sphinx_jobs
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,128 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe ThinkingSphinx::Deltas::DelayedDelta do
4
+ describe '#index' do
5
+ before :each do
6
+ ThinkingSphinx.updates_enabled = true
7
+ ThinkingSphinx.deltas_enabled = true
8
+ ThinkingSphinx::Configuration.instance.delayed_job_priority = 2
9
+
10
+ ThinkingSphinx::Deltas::Job.stub!(:enqueue => true)
11
+ Delayed::Job.stub!(:enqueue => true, :inspect => "Delayed::Job")
12
+
13
+ @delayed_delta = ThinkingSphinx::Deltas::DelayedDelta.new(
14
+ stub('instance'), {}
15
+ )
16
+ @delayed_delta.stub!(:toggled => true)
17
+
18
+ @model = stub('foo')
19
+ @model.stub!(:name => 'foo')
20
+ @model.stub!(:source_of_sphinx_index => @model)
21
+ @model.stub!(:core_index_names => ['foo_core'])
22
+ @model.stub!(:delta_index_names => ['foo_delta'])
23
+
24
+ @instance = stub('instance')
25
+ @instance.stub!(:sphinx_document_id => 42)
26
+ end
27
+
28
+ context 'updates disabled' do
29
+ before :each do
30
+ ThinkingSphinx.updates_enabled = false
31
+ end
32
+
33
+ it "should not enqueue a delta job" do
34
+ ThinkingSphinx::Deltas::Job.should_not_receive(:enqueue)
35
+
36
+ @delayed_delta.index(@model)
37
+ end
38
+
39
+ it "should not enqueue a flag as deleted job" do
40
+ Delayed::Job.should_not_receive(:enqueue)
41
+
42
+ @delayed_delta.index(@model)
43
+ end
44
+ end
45
+
46
+ context 'deltas disabled' do
47
+ before :each do
48
+ ThinkingSphinx.deltas_enabled = false
49
+ end
50
+
51
+ it "should not enqueue a delta job" do
52
+ ThinkingSphinx::Deltas::Job.should_not_receive(:enqueue)
53
+
54
+ @delayed_delta.index(@model)
55
+ end
56
+
57
+ it "should not enqueue a flag as deleted job" do
58
+ Delayed::Job.should_not_receive(:enqueue)
59
+
60
+ @delayed_delta.index(@model)
61
+ end
62
+ end
63
+
64
+ context "instance isn't toggled" do
65
+ before :each do
66
+ @delayed_delta.stub!(:toggled => false)
67
+ end
68
+
69
+ it "should not enqueue a delta job" do
70
+ ThinkingSphinx::Deltas::Job.should_not_receive(:enqueue)
71
+
72
+ @delayed_delta.index(@model, @instance)
73
+ end
74
+
75
+ it "should not enqueue a flag as deleted job" do
76
+ Delayed::Job.should_not_receive(:enqueue)
77
+
78
+ @delayed_delta.index(@model, @instance)
79
+ end
80
+ end
81
+
82
+ it "should enqueue a delta job for the appropriate indexes" do
83
+ ThinkingSphinx::Deltas::Job.should_receive(:enqueue) do |job, priority|
84
+ job.indexes.should == ['foo_delta']
85
+ end
86
+
87
+ @delayed_delta.index(@model)
88
+ end
89
+
90
+ it "should use the defined priority for the delta job" do
91
+ ThinkingSphinx::Deltas::Job.should_receive(:enqueue) do |job, priority|
92
+ priority.should == 2
93
+ end
94
+
95
+ @delayed_delta.index(@model)
96
+ end
97
+
98
+ it "should enqueue a flag-as-deleted job for the appropriate indexes" do
99
+ Delayed::Job.should_receive(:enqueue) do |job, priority|
100
+ job.indexes.should == ['foo_core']
101
+ end
102
+
103
+ @delayed_delta.index(@model, @instance)
104
+ end
105
+
106
+ it "should enqueue a flag-as-deleted job for the appropriate id" do
107
+ Delayed::Job.should_receive(:enqueue) do |job, priority|
108
+ job.document_id.should == 42
109
+ end
110
+
111
+ @delayed_delta.index(@model, @instance)
112
+ end
113
+
114
+ it "should use the defined priority for the flag-as-deleted job" do
115
+ Delayed::Job.should_receive(:enqueue) do |job, priority|
116
+ priority.should == 2
117
+ end
118
+
119
+ @delayed_delta.index(@model, @instance)
120
+ end
121
+
122
+ it "should not enqueue a flag-as-deleted job if no instance is provided" do
123
+ Delayed::Job.should_not_receive(:enqueue)
124
+
125
+ @delayed_delta.index(@model)
126
+ end
127
+ end
128
+ end
metadata ADDED
@@ -0,0 +1,148 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: namxam-ts-delayed-delta
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 1
7
+ - 0
8
+ - 3
9
+ version: 1.0.3
10
+ platform: ruby
11
+ authors:
12
+ - Pat Allan
13
+ - Maximilian Schulz
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-02-26 00:00:00 +01:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: thinking-sphinx
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 1
30
+ - 3
31
+ - 6
32
+ version: 1.3.6
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: delayed_job
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ segments:
43
+ - 1
44
+ - 8
45
+ - 4
46
+ version: 1.8.4
47
+ type: :runtime
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: rspec
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ segments:
57
+ - 1
58
+ - 2
59
+ - 9
60
+ version: 1.2.9
61
+ type: :development
62
+ version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: yard
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ segments:
71
+ - 0
72
+ version: "0"
73
+ type: :development
74
+ version_requirements: *id004
75
+ - !ruby/object:Gem::Dependency
76
+ name: cucumber
77
+ prerelease: false
78
+ requirement: &id005 !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ segments:
83
+ - 0
84
+ version: "0"
85
+ type: :development
86
+ version_requirements: *id005
87
+ description: Manage delta indexes via Delayed Job for Thinking Sphinx (including fix for bundler)
88
+ email: max@jungeelite.de
89
+ executables: []
90
+
91
+ extensions: []
92
+
93
+ extra_rdoc_files:
94
+ - LICENSE
95
+ - README.textile
96
+ files:
97
+ - LICENSE
98
+ - README.textile
99
+ - lib/thinking_sphinx/deltas/delayed_delta.rb
100
+ - lib/thinking_sphinx/deltas/delayed_delta/delta_job.rb
101
+ - lib/thinking_sphinx/deltas/delayed_delta/flag_as_deleted_job.rb
102
+ - lib/thinking_sphinx/deltas/delayed_delta/job.rb
103
+ - lib/thinking_sphinx/deltas/delayed_delta/tasks.rb
104
+ has_rdoc: true
105
+ homepage: http://github.com/namxam/ts-delayed-delta
106
+ licenses: []
107
+
108
+ post_install_message:
109
+ rdoc_options:
110
+ - --charset=UTF-8
111
+ require_paths:
112
+ - lib
113
+ required_ruby_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ segments:
118
+ - 0
119
+ version: "0"
120
+ required_rubygems_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ segments:
125
+ - 0
126
+ version: "0"
127
+ requirements: []
128
+
129
+ rubyforge_project:
130
+ rubygems_version: 1.3.6
131
+ signing_key:
132
+ specification_version: 3
133
+ summary: Thinking Sphinx - Delayed Deltas
134
+ test_files:
135
+ - features/delayed_deltas.feature
136
+ - features/step_definitions/common_steps.rb
137
+ - features/step_definitions/delayed_delta_steps.rb
138
+ - features/support/database.example.yml
139
+ - features/support/db/fixtures/delayed_betas.rb
140
+ - features/support/db/migrations/create_delayed_betas.rb
141
+ - features/support/env.rb
142
+ - features/support/models/delayed_beta.rb
143
+ - spec/spec.opts
144
+ - spec/spec_helper.rb
145
+ - spec/thinking_sphinx/deltas/delayed_delta/delta_job_spec.rb
146
+ - spec/thinking_sphinx/deltas/delayed_delta/flag_as_deleted_job_spec.rb
147
+ - spec/thinking_sphinx/deltas/delayed_delta/job_spec.rb
148
+ - spec/thinking_sphinx/deltas/delayed_delta_spec.rb