flying-sphinx 0.8.5 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,89 +0,0 @@
1
- class FlyingSphinx::DelayedDelta < ThinkingSphinx::Deltas::DefaultDelta
2
- # Adds a job to the queue, if it doesn't already exist. This is to ensure
3
- # multiple indexing requests for the same delta index don't get added, as the
4
- # index only needs to be processed once.
5
- #
6
- # Because indexing jobs are all the same object, they all get serialised to
7
- # the same YAML value.
8
- #
9
- # @param [Object] object The job, which must respond to the #perform method.
10
- # @param [Integer] priority (0)
11
- #
12
- def self.enqueue(object, priority = 0)
13
- return if duplicates_exist? object
14
-
15
- enqueue_without_duplicates_check object, priority
16
- end
17
-
18
- def self.enqueue_without_duplicates_check(object, priority = 0)
19
- if defined?(Rails) && Rails.version.to_i <= 2
20
- ::Delayed::Job.enqueue(object, priority)
21
- else
22
- ::Delayed::Job.enqueue(object, :priority => priority)
23
- end
24
- end
25
-
26
- # Checks whether a given job already exists in the queue.
27
- #
28
- # @param [Object] object The job
29
- # @return [Boolean] True if a duplicate of the job already exists in the queue
30
- #
31
- def self.duplicates_exist?(object)
32
- ::Delayed::Job.count(
33
- :conditions => {
34
- :handler => object.to_yaml,
35
- :locked_at => nil
36
- }
37
- ) > 0
38
- end
39
-
40
- # Adds a job to the queue for processing the given model's delta index. A job
41
- # for hiding the instance in the core index is also created, if an instance is
42
- # provided.
43
- #
44
- # Neither job will be queued if updates or deltas are disabled, or if the
45
- # instance (when given) is not toggled to be in the delta index. The first two
46
- # options are controlled via ThinkingSphinx.updates_enabled? and
47
- # ThinkingSphinx.deltas_enabled?.
48
- #
49
- # @param [Class] model the ActiveRecord model to index.
50
- # @param [ActiveRecord::Base] instance the instance of the given model that
51
- # has changed. Optional.
52
- # @return [Boolean] true
53
- #
54
- def index(model, instance = nil)
55
- return true if skip? instance
56
-
57
- self.class.enqueue(
58
- FlyingSphinx::IndexRequest.new(model.delta_index_names, true),
59
- delayed_job_priority
60
- )
61
-
62
- self.class.enqueue_without_duplicates_check(
63
- FlyingSphinx::FlagAsDeletedJob.new(
64
- model.core_index_names, instance.sphinx_document_id
65
- ),
66
- delayed_job_priority
67
- ) if instance
68
-
69
- true
70
- end
71
-
72
- private
73
-
74
- def delayed_job_priority
75
- ThinkingSphinx::Configuration.instance.delayed_job_priority
76
- end
77
-
78
- # Checks whether jobs should be enqueued. Only true if updates and deltas are
79
- # enabled, and the instance (if there is one) is toggled.
80
- #
81
- # @param [ActiveRecord::Base, NilClass] instance
82
- # @return [Boolean]
83
- #
84
- def skip?(instance)
85
- !ThinkingSphinx.updates_enabled? ||
86
- !ThinkingSphinx.deltas_enabled? ||
87
- (instance && !toggled(instance))
88
- end
89
- end
@@ -1,41 +0,0 @@
1
- # A simple job for flagging a specified Sphinx document in a given index as
2
- # 'deleted'.
3
- #
4
- class FlyingSphinx::FlagAsDeletedJob
5
- attr_accessor :indices, :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(indices, document_id)
15
- @indices, @document_id = indices, 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
- indices.each do |index|
28
- client.update index, ['sphinx_deleted'], {@document_id => [1]}
29
- end
30
- rescue Riddle::ConnectionError
31
- # If it fails here, so be it.
32
- ensure
33
- true
34
- end
35
-
36
- private
37
-
38
- def client
39
- @client ||= ThinkingSphinx::Configuration.instance.client
40
- end
41
- end
@@ -1,5 +0,0 @@
1
- class FlyingSphinx::HerokuSharedAdapter < ThinkingSphinx::PostgreSQLAdapter
2
- def setup
3
- create_array_accum_function
4
- end
5
- end
@@ -1,110 +0,0 @@
1
- class FlyingSphinx::IndexRequest
2
- attr_reader :index_id, :indices, :async
3
-
4
- INDEX_COMPLETE_CHECKING_INTERVAL = 3
5
-
6
- # Remove all Delta jobs from the queue. If the
7
- # delayed_jobs table does not exist, this method will do nothing.
8
- #
9
- def self.cancel_jobs
10
- return unless defined?(::Delayed) && ::Delayed::Job.table_exists?
11
-
12
- ::Delayed::Job.delete_all "handler LIKE '--- !ruby/object:FlyingSphinx::%'"
13
- end
14
-
15
- def self.output_last_index
16
- index = FlyingSphinx::Configuration.new.api.get('indices/last').body
17
- puts "Index Job Status: #{index.status}"
18
- puts "Index Log:\n#{index.log}"
19
- end
20
-
21
- def initialize(indices = [], async = false)
22
- @indices, @async = indices, async
23
- end
24
-
25
- # Shows index name in Delayed::Job#name.
26
- #
27
- def display_name
28
- "#{self.class.name} for #{indices.join(', ')}"
29
- end
30
-
31
- def index
32
- begin_request
33
- return if async
34
-
35
- while !request_complete?
36
- sleep 3
37
- end
38
- end
39
-
40
- def status_message
41
- raise "Index Request failed to start. Something's not right!" if @index_id.nil?
42
-
43
- status = request_status
44
- case status
45
- when 'FINISHED'
46
- "Index Request has completed:\n#{request_log}"
47
- when 'FAILED'
48
- 'Index Request failed.'
49
- when 'PENDING'
50
- 'Index Request is still pending - something has gone wrong.'
51
- else
52
- "Unknown index response: '#{status}'."
53
- end
54
- end
55
-
56
- # Runs Sphinx's indexer tool to process the index. Currently assumes Sphinx is
57
- # running.
58
- #
59
- # @return [Boolean] true
60
- #
61
- def perform
62
- index
63
- true
64
- end
65
-
66
- private
67
-
68
- def configuration
69
- @configuration ||= FlyingSphinx::Configuration.new
70
- end
71
-
72
- def begin_request
73
- path = 'indices'
74
- path << '/unique' if async
75
- response = api.post path, :indices => indices.join(',')
76
-
77
- @index_id = response.body.id
78
- @request_begun = true
79
-
80
- raise RuntimeError, 'Your account does not support delta indexing. Upgrading plans is probably the best way around this.' if response.body.status == 'BLOCKED'
81
- end
82
-
83
- def request_begun?
84
- @request_begun
85
- end
86
-
87
- def request_complete?
88
- case request_status
89
- when 'FINISHED', 'FAILED'
90
- true
91
- when 'PENDING'
92
- false
93
- else
94
- raise "Unknown index response: '#{response.body}'"
95
- end
96
- end
97
-
98
- def request_log
99
- @request.log
100
- end
101
-
102
- def request_status
103
- @request = api.get("indices/#{index_id}").body
104
- @request.status
105
- end
106
-
107
- def api
108
- configuration.api
109
- end
110
- end
@@ -1,30 +0,0 @@
1
- class FlyingSphinx::SphinxConfiguration
2
- def initialize(thinking_sphinx = ThinkingSphinx::Configuration.instance)
3
- @thinking_sphinx = thinking_sphinx
4
- end
5
-
6
- def upload_to(api)
7
- api.put '/',
8
- :configuration => content,
9
- :sphinx_version => thinking_sphinx.version
10
- end
11
-
12
- def upload_file_to(api, path)
13
- api.put '/',
14
- :configuration => File.read(path),
15
- :sphinx_version => '2.0.4'
16
- end
17
-
18
- private
19
-
20
- attr_reader :thinking_sphinx
21
-
22
- def content
23
- @content ||= begin
24
- thinking_sphinx.generate
25
- thinking_sphinx.configuration.searchd.client_key =
26
- FlyingSphinx::Configuration.new.client_key
27
- thinking_sphinx.configuration.render
28
- end
29
- end
30
- end
@@ -1,147 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe FlyingSphinx::DelayedDelta do
4
- describe '.enqueue' do
5
- before :each do
6
- Delayed::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
- FlyingSphinx::DelayedDelta.enqueue(stub('object'))
13
- end
14
-
15
- it "should not enqueue the job if there's an existing job already" do
16
- Delayed::Job.stub!(:count => 1)
17
- Delayed::Job.should_not_receive(:enqueue)
18
-
19
- FlyingSphinx::DelayedDelta.enqueue(stub('object'))
20
- end
21
- end
22
-
23
- describe '#index' do
24
- let(:config) { ThinkingSphinx::Configuration.instance }
25
- let(:delayed_delta) { FlyingSphinx::DelayedDelta.new stub('instance'), {} }
26
- let(:model) {
27
- stub 'foo',
28
- :name => 'foo',
29
- :core_index_names => ['foo_core'],
30
- :delta_index_names => ['foo_delta']
31
- }
32
- let(:instance) { stub('instance', :sphinx_document_id => 42) }
33
-
34
- before :each do
35
- ThinkingSphinx.updates_enabled = true
36
- ThinkingSphinx.deltas_enabled = true
37
-
38
- config.delayed_job_priority = 2
39
-
40
- FlyingSphinx::DelayedDelta.stub!(:enqueue => true)
41
- Delayed::Job.stub!(:enqueue => true, :inspect => 'Delayed::Job')
42
-
43
- delayed_delta.stub!(:toggled => true)
44
- end
45
-
46
- context 'updates disabled' do
47
- before :each do
48
- ThinkingSphinx.updates_enabled = false
49
- end
50
-
51
- it "should not enqueue a delta job" do
52
- FlyingSphinx::DelayedDelta.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 'deltas disabled' do
65
- before :each do
66
- ThinkingSphinx.deltas_enabled = false
67
- end
68
-
69
- it "should not enqueue a delta job" do
70
- FlyingSphinx::DelayedDelta.should_not_receive(:enqueue)
71
-
72
- delayed_delta.index model
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
79
- end
80
- end
81
-
82
- context "instance isn't toggled" do
83
- before :each do
84
- delayed_delta.stub!(:toggled => false)
85
- end
86
-
87
- it "should not enqueue a delta job" do
88
- FlyingSphinx::DelayedDelta.should_not_receive(:enqueue)
89
-
90
- delayed_delta.index model, instance
91
- end
92
-
93
- it "should not enqueue a flag as deleted job" do
94
- Delayed::Job.should_not_receive(:enqueue)
95
-
96
- delayed_delta.index model, instance
97
- end
98
- end
99
-
100
- it "should enqueue a delta job for the appropriate indexes" do
101
- FlyingSphinx::DelayedDelta.should_receive(:enqueue) do |job, priority|
102
- job.indices.should == ['foo_delta']
103
- job.async.should be_true
104
- end
105
-
106
- delayed_delta.index model
107
- end
108
-
109
- it "should use the defined priority for the delta job" do
110
- FlyingSphinx::DelayedDelta.should_receive(:enqueue) do |job, priority|
111
- priority.should == 2
112
- end
113
-
114
- delayed_delta.index model
115
- end
116
-
117
- it "should enqueue a flag-as-deleted job for the appropriate indexes" do
118
- Delayed::Job.should_receive(:enqueue) do |job, options|
119
- job.indices.should == ['foo_core']
120
- end
121
-
122
- delayed_delta.index model, instance
123
- end
124
-
125
- it "should enqueue a flag-as-deleted job for the appropriate id" do
126
- Delayed::Job.should_receive(:enqueue) do |job, options|
127
- job.document_id.should == 42
128
- end
129
-
130
- delayed_delta.index model, instance
131
- end
132
-
133
- it "should use the defined priority for the flag-as-deleted job" do
134
- Delayed::Job.should_receive(:enqueue) do |job, options|
135
- options[:priority].should == 2
136
- end
137
-
138
- delayed_delta.index model, instance
139
- end
140
-
141
- it "should not enqueue a flag-as-deleted job if no instance is provided" do
142
- Delayed::Job.should_not_receive(:enqueue)
143
-
144
- delayed_delta.index model
145
- end
146
- end
147
- end
@@ -1,45 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe FlyingSphinx::FlagAsDeletedJob do
4
- describe '#perform' do
5
- let(:config) { ThinkingSphinx::Configuration.instance }
6
- let(:client) { stub('client', :update => true) }
7
- let(:job) { FlyingSphinx::FlagAsDeletedJob.new(['foo_core'], 12) }
8
-
9
- before :each do
10
- config.stub!(:client => client)
11
- end
12
-
13
- it "should update the specified index" do
14
- client.should_receive(:update) do |index, attributes, values|
15
- index.should == 'foo_core'
16
- end
17
-
18
- job.perform
19
- end
20
-
21
- it "should update all specified indexes" do
22
- job.indices = ['foo_core', 'bar_core']
23
- client.should_receive(:update).with('foo_core', anything, anything)
24
- client.should_receive(:update).with('bar_core', anything, anything)
25
-
26
- job.perform
27
- end
28
-
29
- it "should update the sphinx_deleted attribute" do
30
- client.should_receive(:update) do |index, attributes, values|
31
- attributes.should == ['sphinx_deleted']
32
- end
33
-
34
- job.perform
35
- end
36
-
37
- it "should set sphinx_deleted for the given document to true" do
38
- client.should_receive(:update) do |index, attributes, values|
39
- values[12].should == [1]
40
- end
41
-
42
- job.perform
43
- end
44
- end
45
- end