riddle 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.textile CHANGED
@@ -81,3 +81,5 @@ Thanks to the following people who have contributed to Riddle in some shape or f
81
81
  * Piotr Sarnacki
82
82
  * Tim Preston
83
83
  * Amir Yalon
84
+ * Sam Goldstein
85
+ * Matt Todd
data/lib/riddle/client.rb CHANGED
@@ -115,7 +115,7 @@ module Riddle
115
115
  :float_range => 2 # SPH_FILTER_FLOATRANGE
116
116
  }
117
117
 
118
- attr_accessor :server, :port, :offset, :limit, :max_matches,
118
+ attr_accessor :servers, :port, :offset, :limit, :max_matches,
119
119
  :match_mode, :sort_mode, :sort_by, :weights, :id_range, :filters,
120
120
  :group_by, :group_function, :group_clause, :group_distinct, :cut_off,
121
121
  :retry_count, :retry_delay, :anchor, :index_weights, :rank_mode,
@@ -134,11 +134,11 @@ module Riddle
134
134
  # Can instantiate with a specific server and port - otherwise it assumes
135
135
  # defaults of localhost and 3312 respectively. All other settings can be
136
136
  # accessed and changed via the attribute accessors.
137
- def initialize(server=nil, port=nil)
137
+ def initialize(servers=nil, port=nil)
138
138
  Riddle.version_warning
139
139
 
140
- @server = server || "localhost"
141
- @port = port || 9312
140
+ @servers = (servers || ["localhost"] ).to_a.shuffle
141
+ @port = port || 9312
142
142
  @socket = nil
143
143
 
144
144
  reset
@@ -177,6 +177,17 @@ module Riddle
177
177
  @select = "*"
178
178
  end
179
179
 
180
+ # The searchd server to query. Servers are removed from @server after a
181
+ # Timeout::Error is hit to allow for fail-over.
182
+ def server
183
+ @servers.first
184
+ end
185
+
186
+ # Backwards compatible writer to the @servers array.
187
+ def server=(server)
188
+ @servers = server.to_a
189
+ end
190
+
180
191
  # Set the geo-anchor point - with the names of the attributes that contain
181
192
  # the latitude and longitude (in radians), and the reference position.
182
193
  # Note that for geocoding to work properly, you must also set
@@ -475,9 +486,18 @@ module Riddle
475
486
  else
476
487
  begin
477
488
  Timeout.timeout(@timeout) { @socket = initialise_connection }
478
- rescue Timeout::Error
479
- raise Riddle::ConnectionError,
480
- "Connection to #{@server} on #{@port} timed out after #{@timeout} seconds"
489
+ rescue Timeout::Error, Riddle::ConnectionError => e
490
+ failed_servers ||= []
491
+ failed_servers << servers.shift
492
+ retry if !servers.empty?
493
+
494
+ case e
495
+ when Timeout::Error
496
+ raise Riddle::ConnectionError,
497
+ "Connection to #{failed_servers.inspect} on #{@port} timed out after #{@timeout} seconds"
498
+ else
499
+ raise e
500
+ end
481
501
  end
482
502
  end
483
503
 
@@ -499,11 +519,13 @@ module Riddle
499
519
  if @socket.nil? || @socket.closed?
500
520
  @socket = nil
501
521
  open_socket
502
- end
503
- begin
522
+ begin
523
+ yield @socket
524
+ ensure
525
+ close_socket
526
+ end
527
+ else
504
528
  yield @socket
505
- ensure
506
- close_socket
507
529
  end
508
530
  end
509
531
 
@@ -530,15 +552,15 @@ module Riddle
530
552
  self.connection.call(self)
531
553
  elsif self.class.connection
532
554
  self.class.connection.call(self)
533
- elsif @server.index('/') == 0
534
- UNIXSocket.new @server
555
+ elsif server.index('/') == 0
556
+ UNIXSocket.new server
535
557
  else
536
- TCPSocket.new @server, @port
558
+ TCPSocket.new server, @port
537
559
  end
538
560
  rescue Errno::ECONNREFUSED => e
539
561
  retry if (tries += 1) < 5
540
562
  raise Riddle::ConnectionError,
541
- "Connection to #{@server} on #{@port} failed. #{e.message}"
563
+ "Connection to #{server} on #{@port} failed. #{e.message}"
542
564
  end
543
565
 
544
566
  socket
@@ -46,9 +46,16 @@ module Riddle
46
46
 
47
47
  def stop
48
48
  return true unless running?
49
- Process.kill('SIGTERM', pid.to_i)
50
- rescue Errno::EINVAL
51
- Process.kill('SIGKILL', pid.to_i)
49
+
50
+ stop_flag = 'stopwait'
51
+ stop_flag = 'stop' if Riddle.loaded_version.split('.').first == '0'
52
+ cmd = %(#{searchd} --pidfile --config "#{@path}" --#{stop_flag})
53
+
54
+ if RUBY_PLATFORM =~ /mswin/
55
+ system("start /B #{cmd} 1> NUL 2>&1")
56
+ else
57
+ `#{cmd}`
58
+ end
52
59
  ensure
53
60
  return !running?
54
61
  end
@@ -34,11 +34,12 @@ class SphinxHelper
34
34
  structure = File.open("spec/fixtures/sql/structure.sql") { |f| f.read }
35
35
  # Block ensures multiple statement transaction is closed.
36
36
  server.query(structure) { |response| }
37
- data = File.open("spec/fixtures/sql/data.sql") { |f|
38
- while line = f.gets
39
- server.query line
40
- end
41
- }
37
+ server.query <<-QUERY
38
+ LOAD DATA LOCAL INFILE '#{@path}/fixtures/sql/data.tsv' INTO TABLE
39
+ `riddle`.`people` FIELDS TERMINATED BY ',' ENCLOSED BY "'" (gender,
40
+ first_name, middle_initial, last_name, street_address, city, state,
41
+ postcode, email, birthday)
42
+ QUERY
42
43
 
43
44
  server.close
44
45
  end
@@ -90,4 +91,4 @@ class SphinxHelper
90
91
  def running?
91
92
  pid && `ps #{pid} | wc -l`.to_i > 1
92
93
  end
93
- end
94
+ end
@@ -222,4 +222,39 @@ describe Riddle::Client do
222
222
  }.should raise_error(Riddle::ConnectionError)
223
223
  end
224
224
  end
225
+
226
+ context "connection fail over" do
227
+ it "should try each of several server addresses after timeouts" do
228
+ client = Riddle::Client.new
229
+ client.port = 3314
230
+ client.servers = %w[localhost 127.0.0.1 0.0.0.0]
231
+ client.timeout = 1
232
+
233
+ TCPSocket.should_receive(:new).with(
234
+ an_instance_of(String), 3314
235
+ ).exactly(3).and_raise Timeout::Error
236
+
237
+ lambda {
238
+ client.send(:connect) { |socket| }
239
+ }.should raise_error(Riddle::ConnectionError)
240
+ end
241
+
242
+ it "should try each of several server addresses after a connection refused" do
243
+ client = Riddle::Client.new
244
+ client.port = 3314
245
+ client.servers = %w[localhost 127.0.0.1 0.0.0.0]
246
+ client.timeout = 1
247
+
248
+ # initialise_socket will retry 5 times before failing,
249
+ # these combined with the multiple server failover should result in 15
250
+ # calls to TCPSocket.new
251
+ TCPSocket.should_receive(:new).with(
252
+ an_instance_of(String), 3314
253
+ ).exactly(3 * 5).and_raise Errno::ECONNREFUSED
254
+
255
+ lambda {
256
+ client.send(:connect) { |socket| }
257
+ }.should raise_error(Riddle::ConnectionError)
258
+ end
259
+ end
225
260
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: riddle
3
3
  version: !ruby/object:Gem::Version
4
- hash: 19
4
+ hash: 31
5
5
  prerelease: false
6
6
  segments:
7
7
  - 1
8
- - 1
8
+ - 2
9
9
  - 0
10
- version: 1.1.0
10
+ version: 1.2.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Pat Allan
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-08-29 00:00:00 +09:00
18
+ date: 2010-11-15 00:00:00 +08:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -116,8 +116,8 @@ homepage: http://riddle.freelancing-gods.com
116
116
  licenses: []
117
117
 
118
118
  post_install_message:
119
- rdoc_options:
120
- - --charset=UTF-8
119
+ rdoc_options: []
120
+
121
121
  require_paths:
122
122
  - lib
123
123
  required_ruby_version: !ruby/object:Gem::Requirement