algoliasearch 1.3.1 → 1.4.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.
@@ -10,7 +10,7 @@ module Algolia
10
10
  # A class which encapsulates the HTTPS communication with the Algolia
11
11
  # API server. Uses the HTTPClient library for low-level HTTP communication.
12
12
  class Client
13
- attr_reader :ssl, :ssl_version, :hosts, :application_id, :api_key, :headers, :connect_timeout, :send_timeout, :receive_timeout, :search_timeout
13
+ attr_reader :ssl, :ssl_version, :hosts, :search_hosts, :application_id, :api_key, :headers, :connect_timeout, :send_timeout, :receive_timeout, :search_timeout
14
14
 
15
15
 
16
16
  def initialize(data = {})
@@ -18,7 +18,8 @@ module Algolia
18
18
  @ssl_version = data[:ssl_version].nil? ? nil : data[:ssl_version]
19
19
  @application_id = data[:application_id]
20
20
  @api_key = data[:api_key]
21
- @hosts = (data[:hosts] || 1.upto(3).map { |i| "#{@application_id}-#{i}.algolia.net" }).shuffle
21
+ @hosts = data[:hosts] || (["#{@application_id}.algolia.net"] + 1.upto(3).map { |i| "#{@application_id}-#{i}.algolia.net" }.shuffle + 1.upto(3).map { |i| "#{@application_id}-#{i}.algolianet.com" }.shuffle)
22
+ @search_hosts = data[:search_hosts] || (["#{@application_id}-dsn.algolia.net"] + 1.upto(3).map { |i| "#{@application_id}-#{i}.algolia.net" }.shuffle + 1.upto(3).map { |i| "#{@application_id}-#{i}.algolianet.com" }.shuffle)
22
23
  @connect_timeout = data[:connect_timeout]
23
24
  @send_timeout = data[:send_timeout]
24
25
  @receive_timeout = data[:receive_timeout]
@@ -35,9 +36,9 @@ module Algolia
35
36
  # with common basic response handling. Will raise a
36
37
  # AlgoliaProtocolError if the response has an error status code,
37
38
  # and will return the parsed JSON body on success, if there is one.
38
- def request(uri, method, data = nil, timeout = nil)
39
+ def request(uri, method, data = nil, timeout = nil, read = false)
39
40
  exceptions = []
40
- thread_local_hosts(timeout).each do |host|
41
+ thread_local_hosts(read, timeout).each do |host|
41
42
  begin
42
43
  return perform_request(host[:session], host[:base_url] + uri, method, data)
43
44
  rescue AlgoliaProtocolError => e
@@ -50,35 +51,36 @@ module Algolia
50
51
  raise AlgoliaProtocolError.new(0, "Cannot reach any host: #{exceptions.map { |e| e.to_s }.join(', ')}")
51
52
  end
52
53
 
53
- def get(uri, timeout = nil)
54
- request(uri, :GET, nil, timeout)
54
+ def get(uri, timeout = nil, read = false)
55
+ request(uri, :GET, nil, timeout, read)
55
56
  end
56
57
 
57
- def post(uri, body = {}, timeout = nil)
58
- request(uri, :POST, body, timeout)
58
+ def post(uri, body = {}, timeout = nil, read = false)
59
+ request(uri, :POST, body, timeout, read)
59
60
  end
60
61
 
61
- def put(uri, body = {}, timeout = nil)
62
- request(uri, :PUT, body, timeout)
62
+ def put(uri, body = {}, timeout = nil, read = false)
63
+ request(uri, :PUT, body, timeout, read)
63
64
  end
64
65
 
65
- def delete(uri, timeout = nil)
66
- request(uri, :DELETE, nil, timeout)
66
+ def delete(uri, timeout = nil, read = false)
67
+ request(uri, :DELETE, nil, timeout, read)
67
68
  end
68
69
 
69
70
  private
70
71
 
71
72
  # This method returns a thread-local array of sessions
72
- #
73
+ #
73
74
  # Since the underlying httpclient library resets the connections pool
74
75
  # if you change any of its attributes, we cannot change the timeout
75
76
  # of an HTTP session dynamically. That being said, having 1 pool per
76
77
  # timeout appears to be the only acceptable solution
77
- def thread_local_hosts(forced_timeout)
78
- Thread.current[:algolia_hosts] ||= {}
79
- Thread.current[:algolia_hosts][forced_timeout.to_s] ||= hosts.map do |host|
78
+ def thread_local_hosts(read, forced_timeout)
79
+ k = read ? :algolia_search_hosts : :algolia_hosts
80
+ Thread.current[k] ||= {}
81
+ Thread.current[k][forced_timeout.to_s] ||= (read ? search_hosts : hosts).map do |host|
80
82
  client = HTTPClient.new
81
- client.ssl_config.ssl_version = @ssl_version if @ssl && @ssl_version
83
+ client.ssl_config.ssl_version = @ssl_version if @ssl && @ssl_version
82
84
  hinfo = {
83
85
  :base_url => "http#{@ssl ? 's' : ''}://#{host}",
84
86
  :session => client
@@ -208,7 +210,7 @@ module Algolia
208
210
  { :indexName => indexName, :params => Protocol.to_query(encoded_params) }
209
211
  end
210
212
  }
211
- Algolia.client.post(Protocol.multiple_queries_uri, requests.to_json, Algolia.client.search_timeout)
213
+ Algolia.client.post(Protocol.multiple_queries_uri, requests.to_json, Algolia.client.search_timeout, true)
212
214
  end
213
215
 
214
216
  #
@@ -281,8 +283,15 @@ module Algolia
281
283
  # @param offset Specify the first entry to retrieve (0-based, 0 is the most recent log entry).
282
284
  # @param length Specify the maximum number of entries to retrieve starting at offset. Maximum allowed value: 1000.
283
285
  #
284
- def Algolia.get_logs(offset = 0, length = 10, only_errors = false)
285
- Algolia.client.get(Protocol.logs(offset, length, only_errors))
286
+ def Algolia.get_logs(offset = 0, length = 10, type = "all")
287
+ if (type.is_a?(true.class))
288
+ if (type)
289
+ type = "error"
290
+ else
291
+ type = "all"
292
+ end
293
+ end
294
+ Algolia.client.get(Protocol.logs(offset, length, type))
286
295
  end
287
296
 
288
297
  # List all existing user keys with their associated ACLs
@@ -359,7 +368,7 @@ module Algolia
359
368
 
360
369
  # Used mostly for testing. Lets you delete the api key global vars.
361
370
  def Algolia.destroy
362
- @@client = Thread.current[:algolia_hosts] = nil
371
+ @@client = Thread.current[:algolia_hosts] = Thread.current[:algolia_search_hosts] = nil
363
372
  self
364
373
  end
365
374
 
data/lib/algolia/index.rb CHANGED
@@ -136,7 +136,7 @@ module Algolia
136
136
  # one is kept and others are removed.
137
137
  def search(query, params = {})
138
138
  encoded_params = Hash[params.map { |k,v| [k.to_s, v.is_a?(Array) ? v.to_json : v] }]
139
- Algolia.client.get(Protocol.search_uri(name, query, encoded_params), Algolia.client.search_timeout)
139
+ Algolia.client.get(Protocol.search_uri(name, query, encoded_params), Algolia.client.search_timeout, true)
140
140
  end
141
141
 
142
142
  #
@@ -158,9 +158,9 @@ module Algolia
158
158
  #
159
159
  def get_object(objectID, attributesToRetrieve = nil)
160
160
  if attributesToRetrieve.nil?
161
- Algolia.client.get(Protocol.object_uri(name, objectID, nil))
161
+ Algolia.client.get(Protocol.object_uri(name, objectID, nil), Algolia.client.search_timeout, true)
162
162
  else
163
- Algolia.client.get(Protocol.object_uri(name, objectID, {:attributes => attributesToRetrieve}))
163
+ Algolia.client.get(Protocol.object_uri(name, objectID, {:attributes => attributesToRetrieve}), Algolia.client.search_timeout, true)
164
164
  end
165
165
  end
166
166
 
@@ -170,7 +170,7 @@ module Algolia
170
170
  # @param objectIDs the array of unique identifier of the objects to retrieve
171
171
  #
172
172
  def get_objects(objectIDs)
173
- Algolia.client.post(Protocol.objects_uri, { :requests => objectIDs.map { |objectID| { :indexName => name, :objectID => objectID } } }.to_json)['results']
173
+ Algolia.client.post(Protocol.objects_uri, { :requests => objectIDs.map { |objectID| { :indexName => name, :objectID => objectID } } }.to_json, Algolia.client.search_timeout, true)['results']
174
174
  end
175
175
 
176
176
  # Wait the publication of a task on the server.
@@ -181,7 +181,7 @@ module Algolia
181
181
  #
182
182
  def wait_task(taskID, timeBeforeRetry = 100)
183
183
  loop do
184
- status = Algolia.client.get(Protocol.task_uri(name, taskID))["status"]
184
+ status = Algolia.client.get(Protocol.task_uri(name, taskID), nil, true)["status"]
185
185
  if status == "published"
186
186
  return
187
187
  end
@@ -540,7 +540,8 @@ module Algolia
540
540
  :attributesToHighlight => [],
541
541
  :attributesToSnippet => [],
542
542
  :facets => disjunctive_facet,
543
- :facetFilters => filters
543
+ :facetFilters => filters,
544
+ :analytics => false
544
545
  })
545
546
  end
546
547
  answers = Algolia.multiple_queries(queries)
@@ -1,3 +1,3 @@
1
1
  module Algolia
2
- VERSION = "1.3.1"
2
+ VERSION = "1.4.0"
3
3
  end
@@ -11,7 +11,7 @@ WebMock.disable!
11
11
  # list indexes
12
12
  WebMock.stub_request(:get, /.*\.algolia\.(io|net)\/1\/indexes/).to_return(:body => '{ "items": [] }')
13
13
  # query index
14
- WebMock.stub_request(:get, /.*\.algolia\.(io|net)\/1\/indexes\/[^\/]+/).to_return(:body => '{}')
14
+ WebMock.stub_request(:get, /.*\.algolia\.(io|net)\/1\/indexes\/[^\/]+/).to_return(:body => '{ "hits": [ { "objectID": 42 } ], "page": 1, "hitsPerPage": 1 }')
15
15
  WebMock.stub_request(:post, /.*\.algolia\.(io|net)\/1\/indexes\/[^\/]+\/query/).to_return(:body => '{}')
16
16
  # delete index
17
17
  WebMock.stub_request(:delete, /.*\.algolia\.(io|net)\/1\/indexes\/[^\/]+/).to_return(:body => '{ "taskID": 42 }')
data/spec/client_spec.rb CHANGED
@@ -262,7 +262,7 @@ describe 'Client' do
262
262
  end
263
263
 
264
264
  it "should get logs" do
265
- res = Algolia.get_logs
265
+ res = Algolia.get_logs(0, 20, true)
266
266
 
267
267
  res['logs'].size.should > 0
268
268
  end
@@ -719,5 +719,23 @@ describe 'Client' do
719
719
  answer['disjunctiveFacets']['stars']['*'].should eq(2)
720
720
  answer['disjunctiveFacets']['stars']['****'].should eq(1)
721
721
  end
722
+
723
+ it 'should apply jobs one after another if synchronous' do
724
+ index = Algolia::Index.new(safe_index_name("sync"))
725
+ begin
726
+ index.add_object! :objectID => 1
727
+ answer = index.search('')
728
+ answer['nbHits'].should eq(1)
729
+ answer['hits'][0]['objectID'].to_i.should eq(1)
730
+ index.clear_index!
731
+ index.add_object! :objectID => 2
732
+ index.add_object! :objectID => 3
733
+ answer = index.search('')
734
+ answer['nbHits'].should eq(2)
735
+ answer['hits'][0]['objectID'].to_i.should_not eq(1)
736
+ ensure
737
+ index.delete_index
738
+ end
739
+ end
722
740
  end
723
741
 
data/spec/mock_spec.rb CHANGED
@@ -6,13 +6,13 @@ describe 'With a mocked client' do
6
6
 
7
7
  before(:each) do
8
8
  WebMock.enable!
9
- Thread.current[:algolia_hosts] = nil # reset session objects
9
+ Thread.current[:algolia_hosts] = Thread.current[:algolia_search_hosts] = nil # reset session objects
10
10
  end
11
11
 
12
12
  it "should add a simple object" do
13
13
  index = Algolia::Index.new("friends")
14
14
  index.add_object!({ :name => "John Doe", :email => "john@doe.org" })
15
- index.search('').should == {} # mocked
15
+ index.search('').should == { "hits" => [ { "objectID" => 42 } ], "page" => 1, "hitsPerPage" => 1 } # mocked
16
16
  index.list_user_keys
17
17
  index.browse
18
18
  index.clear
data/spec/stub_spec.rb CHANGED
@@ -6,7 +6,7 @@ describe 'With a rate limited client' do
6
6
 
7
7
  before(:each) do
8
8
  WebMock.enable!
9
- Thread.current[:algolia_hosts] = nil
9
+ Thread.current[:algolia_hosts] = Thread.current[:algolia_search_hosts] = nil
10
10
  end
11
11
 
12
12
  it "should pass the right headers" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: algoliasearch
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Algolia
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-29 00:00:00.000000000 Z
11
+ date: 2015-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httpclient