flying-sphinx 0.4.4 → 0.5.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.
@@ -6,7 +6,11 @@ unless Rails.env.development? || Rails.env.test?
6
6
 
7
7
  ThinkingSphinx::Configuration.instance.address = config.host
8
8
  ThinkingSphinx::Configuration.instance.port = config.port
9
+ ThinkingSphinx::Configuration.instance.configuration.searchd.client_key =
10
+ config.client_key
9
11
  end
10
12
 
11
- ThinkingSphinx.database_adapter = FlyingSphinx::HerokuSharedAdapter
13
+ if ENV['DATABASE_URL'][/^mysql/].nil?
14
+ ThinkingSphinx.database_adapter = FlyingSphinx::HerokuSharedAdapter
15
+ end
12
16
  end
@@ -8,7 +8,11 @@ class FlyingSphinx::Railtie < Rails::Railtie
8
8
 
9
9
  ThinkingSphinx::Configuration.instance.address = config.host
10
10
  ThinkingSphinx::Configuration.instance.port = config.port
11
+ ThinkingSphinx::Configuration.instance.configuration.searchd.client_key =
12
+ config.client_key
11
13
 
12
- ThinkingSphinx.database_adapter = FlyingSphinx::HerokuSharedAdapter
14
+ if ENV['DATABASE_URL'][/^mysql/].nil?
15
+ ThinkingSphinx.database_adapter = FlyingSphinx::HerokuSharedAdapter
16
+ end
13
17
  end unless Rails.env.development? || Rails.env.test?
14
18
  end
@@ -2,8 +2,10 @@ namespace :fs do
2
2
  task :index => :environment do
3
3
  puts "Starting Index Request"
4
4
  FlyingSphinx::IndexRequest.cancel_jobs
5
- FlyingSphinx::IndexRequest.new.update_and_index
6
- puts "Index Request has completed"
5
+ request = FlyingSphinx::IndexRequest.new
6
+ request.update_and_index
7
+ puts request.status_message
8
+
7
9
  end
8
10
 
9
11
  task :start => :environment do
@@ -20,4 +22,12 @@ namespace :fs do
20
22
 
21
23
  task :restart => [:environment, :stop, :start]
22
24
  task :rebuild => [:environment, :stop, :index, :start]
25
+
26
+ task :index_log => :environment do
27
+ FlyingSphinx::IndexRequest.output_last_index
28
+ end
29
+
30
+ task :actions => :environment do
31
+ FlyingSphinx::Configuration.new.output_recent_actions
32
+ end
23
33
  end
@@ -2,45 +2,54 @@ class FlyingSphinx::Tunnel
2
2
  def self.connect(configuration, &block)
3
3
  tunnel = new configuration
4
4
  tunnel.open do |session|
5
- session.loop &block
5
+ session.loop do
6
+ block.call
7
+ end
6
8
  end
7
9
  end
8
10
 
11
+ def self.required?
12
+ ThinkingSphinx.database_adapter == FlyingSphinx::HerokuSharedAdapter
13
+ end
14
+
9
15
  def initialize(configuration)
10
16
  @configuration = configuration
11
17
  end
12
-
18
+
13
19
  def open(&block)
14
- Net::SSH.start(@configuration.host, 'sphinx', ssh_options) do |session|
15
- session.forward.remote(
16
- db_port, db_host, @configuration.database_port, '0.0.0.0'
17
- )
18
- session.loop { !remote_exists?(session) }
19
-
20
- yield session
21
- end
22
- end
20
+ session = Net::SSH.start(@configuration.host, 'sphinx', ssh_options)
21
+ session.forward.remote(
22
+ db_port, db_host, @configuration.database_port, '0.0.0.0'
23
+ )
24
+
25
+ session.loop { !remote_exists?(session) }
23
26
 
24
- private
27
+ yield session
28
+ rescue IOError
29
+ # Server closed the connection on us. That's (hopefully) expected, nothing
30
+ # to worry about.
31
+ end
25
32
 
33
+ private
34
+
26
35
  def db_host
27
36
  db_config[:host]
28
37
  end
29
-
38
+
30
39
  def db_port
31
40
  db_config[:port]
32
41
  end
33
-
42
+
34
43
  def db_config
35
44
  @db_config ||= ActiveRecord::Base.connection.instance_variable_get(:@config)
36
45
  end
37
-
46
+
38
47
  def ssh_options
39
48
  {:keys => [
40
49
  File.expand_path('../../../keys/key', __FILE__)
41
50
  ]}
42
51
  end
43
-
52
+
44
53
  def remote_exists?(session)
45
54
  session.forward.active_remotes.include?(
46
55
  [@configuration.database_port, '0.0.0.0']
@@ -0,0 +1,23 @@
1
+ require 'rubygems'
2
+ begin
3
+ require 'bundler'
4
+ rescue LoadError
5
+ puts "although not required, it's recommended you use bundler during development"
6
+ end
7
+
8
+ require 'timeout'
9
+
10
+ require 'thinking-sphinx'
11
+ require 'flying_sphinx'
12
+ require 'delayed_job'
13
+
14
+ require 'fakeweb'
15
+ require 'fakeweb_matcher'
16
+
17
+ FakeWeb.allow_net_connect = false
18
+
19
+ Delayed::Worker.backend = :active_record
20
+
21
+ # we don't want a checking of interval in testing
22
+ FlyingSphinx::IndexRequest.send(:remove_const, :INDEX_COMPLETE_CHECKING_INTERVAL)
23
+ FlyingSphinx::IndexRequest::INDEX_COMPLETE_CHECKING_INTERVAL = 0
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+ require 'multi_json'
3
+
4
+ describe FlyingSphinx::Configuration do
5
+ describe '#initialize' do
6
+ let(:api_server) { 'https://flying-sphinx.com/api/my' }
7
+ let(:api_key) { 'foo-bar-baz' }
8
+ let(:identifier) { 'app@heroku.com' }
9
+ let(:config) { FlyingSphinx::Configuration.new identifier, api_key }
10
+
11
+ before :each do
12
+ FakeWeb.register_uri(:get, "#{api_server}/app",
13
+ :body => MultiJson.encode(
14
+ :server => 'foo.bar.com',
15
+ :port => 9319,
16
+ :database_port => 10001
17
+ )
18
+ )
19
+ end
20
+
21
+ it "requests details from the server with the given API key" do
22
+ config
23
+ FakeWeb.should have_requested :get, "#{api_server}/app"
24
+ end
25
+
26
+ it "sets the host from the server information" do
27
+ config.host.should == 'foo.bar.com'
28
+ end
29
+
30
+ it "sets the port from the server information" do
31
+ config.port.should == 9319
32
+ end
33
+
34
+ it "sets the port from the server information" do
35
+ config.database_port.should == 10001
36
+ end
37
+ end
38
+ end
File without changes
@@ -0,0 +1,176 @@
1
+ require 'spec_helper'
2
+
3
+ describe FlyingSphinx::IndexRequest do
4
+ let(:api) { FlyingSphinx::API.new 'foo', 'bar' }
5
+ let(:configuration) {
6
+ stub(:configuration, :api => api, :sphinx_configuration => 'foo {}')
7
+ }
8
+
9
+ let(:index_response) {
10
+ stub(:response, :body => stub(:body, :id => 42, :status => 'OK'))
11
+ }
12
+ let(:blocked_response) {
13
+ stub(:response, :body => stub(:body, :id => nil, :status => 'BLOCKED'))
14
+ }
15
+
16
+ before :each do
17
+ ThinkingSphinx.database_adapter = FlyingSphinx::HerokuSharedAdapter
18
+
19
+ FlyingSphinx::Configuration.stub!(:new => configuration)
20
+ FlyingSphinx::Tunnel.stub(:connect) { |config, block| block.call }
21
+ end
22
+
23
+ describe '.cancel_jobs' do
24
+ before :each do
25
+ Delayed::Job.stub!(:delete_all => true)
26
+ end
27
+
28
+ it "should not delete any rows if the delayed_jobs table does not exist" do
29
+ Delayed::Job.stub!(:table_exists? => false)
30
+ Delayed::Job.should_not_receive(:delete_all)
31
+
32
+ FlyingSphinx::IndexRequest.cancel_jobs
33
+ end
34
+
35
+ it "should delete rows if the delayed_jobs table does exist" do
36
+ Delayed::Job.stub!(:table_exists? => true)
37
+ Delayed::Job.should_receive(:delete_all)
38
+
39
+ FlyingSphinx::IndexRequest.cancel_jobs
40
+ end
41
+
42
+ it "should delete only Thinking Sphinx jobs" do
43
+ Delayed::Job.stub!(:table_exists? => true)
44
+ Delayed::Job.should_receive(:delete_all) do |sql|
45
+ sql.should match(/handler LIKE '--- !ruby\/object:FlyingSphinx::\%'/)
46
+ end
47
+
48
+ FlyingSphinx::IndexRequest.cancel_jobs
49
+ end
50
+ end
51
+
52
+ describe '#update_and_index' do
53
+ let(:index_request) { FlyingSphinx::IndexRequest.new }
54
+ let(:conf_params) { { :configuration => 'foo {}' } }
55
+ let(:index_params) { { :indices => '' } }
56
+
57
+ it "makes a new request" do
58
+ api.should_receive(:put).with('/', conf_params).and_return('ok')
59
+ api.should_receive(:post).
60
+ with('indices', index_params).and_return(index_response)
61
+
62
+ begin
63
+ Timeout::timeout(0.2) {
64
+ index_request.update_and_index
65
+ }
66
+ rescue Timeout::Error
67
+ end
68
+ end
69
+
70
+ context 'delta request without delta support' do
71
+ it "should explain why the request failed" do
72
+ api.should_receive(:put).
73
+ with('/', conf_params).and_return('ok')
74
+ api.should_receive(:post).
75
+ with('indices', index_params).and_return(blocked_response)
76
+ index_request.should_receive(:puts).
77
+ with('Your account does not support delta indexing. Upgrading plans is probably the best way around this.')
78
+
79
+ index_request.update_and_index
80
+ end
81
+ end
82
+
83
+ context 'request for a MySQL database' do
84
+ before :each do
85
+ ThinkingSphinx.database_adapter = nil
86
+ end
87
+
88
+ after :each do
89
+ ThinkingSphinx.database_adapter = FlyingSphinx::HerokuSharedAdapter
90
+ end
91
+
92
+ it "should not establish an SSH connection" do
93
+ FlyingSphinx::Tunnel.should_not_receive(:connect)
94
+
95
+ api.should_receive(:put).with('/', conf_params).and_return('ok')
96
+ api.should_receive(:post).
97
+ with('indices', index_params).and_return(index_response)
98
+ api.should_receive(:get).with('indices/42').
99
+ and_return(stub(:response, :body => stub(:body, :status => 'FINISHED')))
100
+
101
+ index_request.update_and_index
102
+ end
103
+ end
104
+ end
105
+
106
+ describe '#perform' do
107
+ let(:index_request) { FlyingSphinx::IndexRequest.new ['foo_delta'] }
108
+ let(:index_params) { { :indices => 'foo_delta' } }
109
+
110
+ it "makes a new request" do
111
+ api.should_receive(:post).
112
+ with('indices', index_params).and_return(index_response)
113
+
114
+ begin
115
+ Timeout::timeout(0.2) {
116
+ index_request.perform
117
+ }
118
+ rescue Timeout::Error
119
+ end
120
+ end
121
+ end
122
+
123
+ describe '#status_message' do
124
+ let(:index_request) { FlyingSphinx::IndexRequest.new }
125
+ let(:finished_response) {
126
+ stub(:response, :body => stub(:body, :status => 'FINISHED'))
127
+ }
128
+ let(:failure_response) {
129
+ stub(:response, :body => stub(:body, :status => 'FAILED'))
130
+ }
131
+ let(:pending_response) {
132
+ stub(:response, :body => stub(:body, :status => 'PENDING'))
133
+ }
134
+ let(:unknown_response) {
135
+ stub(:response, :body => stub(:body, :status => 'UNKNOWN'))
136
+ }
137
+
138
+ before :each do
139
+ api.stub(:post => index_response)
140
+ end
141
+
142
+ it "returns with a positive message on success" do
143
+ api.stub(:get => finished_response)
144
+
145
+ index_request.status_message.should == 'Index Request has completed.'
146
+ end
147
+
148
+ it "returns with a failure message on failure" do
149
+ api.stub(:get => failure_response)
150
+
151
+ index_request.status_message.should == 'Index Request failed.'
152
+ end
153
+
154
+ it "warns the user if the request is still pending" do
155
+ api.stub(:get => pending_response)
156
+
157
+ index_request.status_message.should == 'Index Request is still pending - something has gone wrong.'
158
+ end
159
+
160
+ it "treats all other statuses as unknown" do
161
+ api.stub(:get => unknown_response)
162
+
163
+ index_request.status_message.should == "Unknown index response: 'UNKNOWN'."
164
+ end
165
+ end
166
+
167
+ describe "#display_name" do
168
+ let(:index_request) {
169
+ FlyingSphinx::IndexRequest.new ['foo_core', 'bar_core']
170
+ }
171
+
172
+ it "should display class name with all indexes" do
173
+ index_request.display_name.should == "FlyingSphinx::IndexRequest for foo_core, bar_core"
174
+ end
175
+ end
176
+ end
metadata CHANGED
@@ -1,13 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flying-sphinx
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 4
9
- - 4
10
- version: 0.4.4
4
+ prerelease:
5
+ version: 0.5.0
11
6
  platform: ruby
12
7
  authors:
13
8
  - Pat Allan
@@ -15,167 +10,141 @@ autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
12
 
18
- date: 2011-02-07 00:00:00 +11:00
13
+ date: 2011-05-12 00:00:00 +10:00
19
14
  default_executable:
20
15
  dependencies:
21
16
  - !ruby/object:Gem::Dependency
22
- type: :runtime
23
- prerelease: false
24
17
  name: thinking-sphinx
25
- version_requirements: &id001 !ruby/object:Gem::Requirement
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
26
20
  none: false
27
21
  requirements:
28
22
  - - ">="
29
23
  - !ruby/object:Gem::Version
30
- hash: 3
31
- segments:
32
- - 0
33
24
  version: "0"
34
- requirement: *id001
35
- - !ruby/object:Gem::Dependency
36
25
  type: :runtime
37
- prerelease: false
26
+ version_requirements: *id001
27
+ - !ruby/object:Gem::Dependency
38
28
  name: net-ssh
39
- version_requirements: &id002 !ruby/object:Gem::Requirement
29
+ prerelease: false
30
+ requirement: &id002 !ruby/object:Gem::Requirement
40
31
  none: false
41
32
  requirements:
42
33
  - - ~>
43
34
  - !ruby/object:Gem::Version
44
- hash: 33
45
- segments:
46
- - 2
47
- - 0
48
- - 23
49
35
  version: 2.0.23
50
- requirement: *id002
51
- - !ruby/object:Gem::Dependency
52
36
  type: :runtime
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: multi_json
53
40
  prerelease: false
54
- name: json
55
- version_requirements: &id003 !ruby/object:Gem::Requirement
41
+ requirement: &id003 !ruby/object:Gem::Requirement
56
42
  none: false
57
43
  requirements:
58
44
  - - ~>
59
45
  - !ruby/object:Gem::Version
60
- hash: 11
61
- segments:
62
- - 1
63
- - 4
64
- - 6
65
- version: 1.4.6
66
- requirement: *id003
67
- - !ruby/object:Gem::Dependency
46
+ version: 1.0.1
68
47
  type: :runtime
48
+ version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: faraday
69
51
  prerelease: false
70
- name: httparty
71
- version_requirements: &id004 !ruby/object:Gem::Requirement
52
+ requirement: &id004 !ruby/object:Gem::Requirement
72
53
  none: false
73
54
  requirements:
74
55
  - - ~>
75
56
  - !ruby/object:Gem::Version
76
- hash: 5
77
- segments:
78
- - 0
79
- - 6
80
- - 1
81
57
  version: 0.6.1
82
- requirement: *id004
58
+ type: :runtime
59
+ version_requirements: *id004
83
60
  - !ruby/object:Gem::Dependency
84
- type: :development
61
+ name: faraday_middleware
85
62
  prerelease: false
86
- name: jeweler
87
- version_requirements: &id005 !ruby/object:Gem::Requirement
63
+ requirement: &id005 !ruby/object:Gem::Requirement
88
64
  none: false
89
65
  requirements:
90
- - - "="
66
+ - - ~>
91
67
  - !ruby/object:Gem::Version
92
- hash: 1
93
- segments:
94
- - 1
95
- - 5
96
- - 1
97
- version: 1.5.1
98
- requirement: *id005
68
+ version: 0.6.3
69
+ type: :runtime
70
+ version_requirements: *id005
99
71
  - !ruby/object:Gem::Dependency
100
- type: :development
72
+ name: rash
101
73
  prerelease: false
102
- name: rspec
103
- version_requirements: &id006 !ruby/object:Gem::Requirement
74
+ requirement: &id006 !ruby/object:Gem::Requirement
104
75
  none: false
105
76
  requirements:
106
- - - "="
77
+ - - ~>
107
78
  - !ruby/object:Gem::Version
108
- hash: 11
109
- segments:
110
- - 2
111
- - 1
112
- - 0
113
- version: 2.1.0
114
- requirement: *id006
79
+ version: 0.3.0
80
+ type: :runtime
81
+ version_requirements: *id006
115
82
  - !ruby/object:Gem::Dependency
116
- type: :development
83
+ name: yajl-ruby
117
84
  prerelease: false
118
- name: rcov
119
- version_requirements: &id007 !ruby/object:Gem::Requirement
85
+ requirement: &id007 !ruby/object:Gem::Requirement
120
86
  none: false
121
87
  requirements:
122
- - - "="
88
+ - - ~>
123
89
  - !ruby/object:Gem::Version
124
- hash: 43
125
- segments:
126
- - 0
127
- - 9
128
- - 8
129
- version: 0.9.8
130
- requirement: *id007
90
+ version: 0.8.2
91
+ type: :development
92
+ version_requirements: *id007
131
93
  - !ruby/object:Gem::Dependency
94
+ name: rspec
95
+ prerelease: false
96
+ requirement: &id008 !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: 2.5.0
132
102
  type: :development
103
+ version_requirements: *id008
104
+ - !ruby/object:Gem::Dependency
105
+ name: rcov
133
106
  prerelease: false
107
+ requirement: &id009 !ruby/object:Gem::Requirement
108
+ none: false
109
+ requirements:
110
+ - - ~>
111
+ - !ruby/object:Gem::Version
112
+ version: 0.9.9
113
+ type: :development
114
+ version_requirements: *id009
115
+ - !ruby/object:Gem::Dependency
134
116
  name: fakeweb
135
- version_requirements: &id008 !ruby/object:Gem::Requirement
117
+ prerelease: false
118
+ requirement: &id010 !ruby/object:Gem::Requirement
136
119
  none: false
137
120
  requirements:
138
- - - "="
121
+ - - ~>
139
122
  - !ruby/object:Gem::Version
140
- hash: 27
141
- segments:
142
- - 1
143
- - 3
144
- - 0
145
123
  version: 1.3.0
146
- requirement: *id008
147
- - !ruby/object:Gem::Dependency
148
124
  type: :development
149
- prerelease: false
125
+ version_requirements: *id010
126
+ - !ruby/object:Gem::Dependency
150
127
  name: fakeweb-matcher
151
- version_requirements: &id009 !ruby/object:Gem::Requirement
128
+ prerelease: false
129
+ requirement: &id011 !ruby/object:Gem::Requirement
152
130
  none: false
153
131
  requirements:
154
- - - "="
132
+ - - ~>
155
133
  - !ruby/object:Gem::Version
156
- hash: 27
157
- segments:
158
- - 1
159
- - 2
160
- - 2
161
134
  version: 1.2.2
162
- requirement: *id009
163
- - !ruby/object:Gem::Dependency
164
135
  type: :development
165
- prerelease: false
136
+ version_requirements: *id011
137
+ - !ruby/object:Gem::Dependency
166
138
  name: delayed_job
167
- version_requirements: &id010 !ruby/object:Gem::Requirement
139
+ prerelease: false
140
+ requirement: &id012 !ruby/object:Gem::Requirement
168
141
  none: false
169
142
  requirements:
170
- - - "="
143
+ - - ~>
171
144
  - !ruby/object:Gem::Version
172
- hash: 15
173
- segments:
174
- - 2
175
- - 1
176
- - 2
177
- version: 2.1.2
178
- requirement: *id010
145
+ version: 2.1.4
146
+ type: :development
147
+ version_requirements: *id012
179
148
  description: Hooks Thinking Sphinx into the Flying Sphinx service
180
149
  email: pat@freelancing-gods.com
181
150
  executables: []
@@ -185,9 +154,13 @@ extensions: []
185
154
  extra_rdoc_files:
186
155
  - README.textile
187
156
  files:
157
+ - .gitignore
158
+ - Gemfile
188
159
  - LICENCE
189
160
  - README.textile
161
+ - Rakefile
190
162
  - VERSION
163
+ - flying-sphinx.gemspec
191
164
  - keys/key
192
165
  - lib/flying-sphinx.rb
193
166
  - lib/flying_sphinx.rb
@@ -201,15 +174,20 @@ files:
201
174
  - lib/flying_sphinx/railtie.rb
202
175
  - lib/flying_sphinx/tasks.rb
203
176
  - lib/flying_sphinx/tunnel.rb
204
- - spec/flying_sphinx/configuration_spec.rb
205
- - spec/flying_sphinx/delayed_delta_spec.rb
206
- - spec/flying_sphinx/flag_as_deleted_job_spec.rb
207
- - spec/flying_sphinx/index_request_spec.rb
177
+ - spec/spec_helper.rb
178
+ - spec/specs/configuration_spec.rb
179
+ - spec/specs/delayed_delta_spec.rb
180
+ - spec/specs/flag_as_deleted_job_spec.rb
181
+ - spec/specs/index_request_spec.rb
208
182
  has_rdoc: true
209
183
  homepage: https://flying-sphinx.com
210
184
  licenses: []
211
185
 
212
- post_install_message:
186
+ post_install_message: |
187
+ If you're upgrading, you should rebuild your Sphinx setup when deploying:
188
+
189
+ $ heroku rake fs:rebuild
190
+
213
191
  rdoc_options: []
214
192
 
215
193
  require_paths:
@@ -219,28 +197,23 @@ required_ruby_version: !ruby/object:Gem::Requirement
219
197
  requirements:
220
198
  - - ">="
221
199
  - !ruby/object:Gem::Version
222
- hash: 3
223
- segments:
224
- - 0
225
200
  version: "0"
226
201
  required_rubygems_version: !ruby/object:Gem::Requirement
227
202
  none: false
228
203
  requirements:
229
204
  - - ">="
230
205
  - !ruby/object:Gem::Version
231
- hash: 3
232
- segments:
233
- - 0
234
206
  version: "0"
235
207
  requirements: []
236
208
 
237
209
  rubyforge_project:
238
- rubygems_version: 1.3.7
210
+ rubygems_version: 1.6.2
239
211
  signing_key:
240
212
  specification_version: 3
241
213
  summary: Sphinx in the Cloud
242
214
  test_files:
243
- - spec/flying_sphinx/configuration_spec.rb
244
- - spec/flying_sphinx/delayed_delta_spec.rb
245
- - spec/flying_sphinx/flag_as_deleted_job_spec.rb
246
- - spec/flying_sphinx/index_request_spec.rb
215
+ - spec/spec_helper.rb
216
+ - spec/specs/configuration_spec.rb
217
+ - spec/specs/delayed_delta_spec.rb
218
+ - spec/specs/flag_as_deleted_job_spec.rb
219
+ - spec/specs/index_request_spec.rb