algoliasearch 1.4.0 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 60f96e5a2607dcefc2d61bfd860ee85334fc4974
4
- data.tar.gz: 13a0e314c0fb5df77b4189030e6505e76a7f8924
3
+ metadata.gz: d9df8ced9c8a5da4e7e677c2643b24891b84a406
4
+ data.tar.gz: ea2d150a9d5171f5e4da18a6a5c7758137d31aa5
5
5
  SHA512:
6
- metadata.gz: 84e2f40e68e6a1114196025eba308416ddcf6156d4bec2bf99cba69a5d0420d279c0d1294df2200eb07c6dc5d0749d3ff943f1c17f80ed62e707799e20dcb796
7
- data.tar.gz: b2fd8567ef442cd5b987a684fb56a5c83d5b753034a62dffdc551b16a69862ea92d733a95eda3ddf532d2b99105ea8761c48a86e48e8f9fb57a8d58617cef635
6
+ metadata.gz: 04a47d4b5227e7e97db5d33fb1759a3c053e0e34a94fb6d7eb380c97a4ae4dbfc097df30755afa2524f41cc93400d19c2b3db5d70676cd9a5469ba68cadab3e4
7
+ data.tar.gz: 088ba592a94f6e31dd3d0f07f5668b53bb63932fd8680e84c03da0dc7a0add25aaa8a8bfca3f8c9b43ec797d0288391611ec441f89d0bfa77a188de3ffbfdbd8
data/ChangeLog CHANGED
@@ -1,5 +1,8 @@
1
1
  CHANGELOG
2
2
 
3
+ 2015-04-10 1.4.1
4
+ * Force the default connect/read/write/search/batch timeouts to Algolia-specific values
5
+
3
6
  2015-03-17 1.4.0
4
7
  * High-available DNS: search queries are now targeting "APPID-DSN.algolia.net" first, then the main cluster using NSOne, then the main cluster using Route53.
5
8
  Indexing queries are targeting "APPID.algolia.net" first, then the main cluster using NSOne, then the main cluster using Route53.
data/README.md CHANGED
@@ -3,21 +3,8 @@
3
3
 
4
4
 
5
5
  [Algolia Search](http://www.algolia.com) is a hosted full-text, numerical, and faceted search engine capable of delivering realtime results from the first keystroke.
6
- Algolia's Search API makes it easy to deliver a great search experience in your websites and mobile applications by providing:
7
6
 
8
- * REST and JSON based API
9
- * Search against infinite attributes from a single search box
10
- * Instant search as you type experience
11
- * Relevance and popularity ranking
12
- * Global language support
13
- * Typo tolerance in any language
14
- * Smart highlighting
15
- * Facet as you type
16
- * Geo awareness
17
- * 99.99% SLA
18
- * First class data security
19
-
20
- Our Ruby client lets you easily use the [Algolia Search API](http://www.algolia.com) from your backend. It wraps the [Algolia Search REST API](http://www.algolia.com/doc/rest_api).
7
+ Our Ruby client lets you easily use the [Algolia Search API](https://www.algolia.com/doc/rest_api) from your backend. It wraps the [Algolia Search REST API](http://www.algolia.com/doc/rest_api).
21
8
 
22
9
 
23
10
  [![Build Status](https://travis-ci.org/algolia/algoliasearch-client-ruby.svg?branch=master)](https://travis-ci.org/algolia/algoliasearch-client-ruby) [![Gem Version](https://badge.fury.io/rb/algoliasearch.svg)](http://badge.fury.io/rb/algoliasearch) [![Code Climate](https://codeclimate.com/github/algolia/algoliasearch-client-ruby.svg)](https://codeclimate.com/github/algolia/algoliasearch-client-ruby) [![Coverage Status](https://coveralls.io/repos/algolia/algoliasearch-client-ruby/badge.png)](https://coveralls.io/r/algolia/algoliasearch-client-ruby)
@@ -131,25 +118,35 @@ puts index.search('jim').to_json
131
118
 
132
119
  **Notes:** If you are building a web application, you may be more interested in using our [JavaScript client](https://github.com/algolia/algoliasearch-client-js) to perform queries. It brings two benefits:
133
120
  * Your users get a better response time by not going through your servers
134
- * It will offload unnecessary tasks from your servers.
121
+ * It will offload unnecessary tasks from your servers
135
122
 
136
123
  ```html
137
- <script type="text/javascript" src="//path/to/algoliasearch.min.js"></script>
138
- <script type="text/javascript">
139
- var client = new AlgoliaSearch("YourApplicationID", "YourSearchOnlyAPIKey");
140
- var index = client.initIndex('YourIndexName');
141
-
142
- function searchCallback(success, content) {
143
- if (success) {
144
- console.log(content);
145
- }
124
+ <script src="//cdn.jsdelivr.net/algoliasearch/3/algoliasearch.min.js"></script>
125
+ <script>
126
+ var client = algoliasearch('ApplicationID', 'Search-Only-API-Key');
127
+ var index = client.initIndex('indexName');
128
+
129
+ // perform query "jim"
130
+ index.search('jim', searchCallback);
131
+
132
+ // the last optional argument can be used to add search parameters
133
+ index.search(
134
+ 'jim', {
135
+ hitsPerPage: 5,
136
+ facets: '*',
137
+ maxValuesPerFacet: 10
138
+ },
139
+ searchCallback
140
+ );
141
+
142
+ function searchCallback(err, content) {
143
+ if (err) {
144
+ console.error(err);
145
+ return;
146
146
  }
147
147
 
148
- // perform query "jim"
149
- index.search("jim", searchCallback);
150
-
151
- // the last optional argument can be used to add search parameters
152
- index.search("jim", searchCallback, { hitsPerPage: 5, facets: '*', maxValuesPerFacet: 10 });
148
+ console.log(content);
149
+ }
153
150
  </script>
154
151
  ```
155
152
 
@@ -390,7 +387,7 @@ res = index.search("query string", { "attributesToRetrieve" => "firstname,lastna
390
387
 
391
388
  The server response will look like:
392
389
 
393
- ```javascript
390
+ ```json
394
391
  {
395
392
  "hits": [
396
393
  {
@@ -458,6 +455,7 @@ res = index.get_object("myID", "fistname")
458
455
 
459
456
  You can also retrieve a set of objects:
460
457
 
458
+
461
459
  ```ruby
462
460
  res = index.get_objects(["myID", "myID2"])
463
461
  ```
@@ -466,6 +464,7 @@ res = index.get_objects(["myID", "myID2"])
466
464
 
467
465
 
468
466
 
467
+
469
468
  Delete an object
470
469
  -------------
471
470
 
@@ -740,15 +739,23 @@ You may have a single index containing per user data. In that case, all records
740
739
  public_key = Algolia.generate_secured_api_key 'YourSearchOnlyApiKey', '(public,user_42)'
741
740
  ```
742
741
 
743
- This public API key must then be used in your JavaScript code as follow:
742
+ This public API key can then be used in your JavaScript code as follow:
744
743
 
745
744
  ```javascript
746
745
  <script type="text/javascript">
747
- var algolia = new AlgoliaSearch('YourApplicationID', '<%= public_api_key %>');
748
- algolia.setSecurityTags('(public,user_42)'); // must be same than those used at generation-time
749
- algolia.initIndex('YourIndex').search($('#q').val(), function(success, content) {
750
- // [...]
751
- });
746
+ var client = algoliasearch('YourApplicationID', '<%= public_api_key %>');
747
+ client.setSecurityTags('(public,user_42)'); // must be same than those used at generation-time
748
+
749
+ var index = client.initIndex('indexName')
750
+
751
+ index.search('something', function(err, content) {
752
+ if (err) {
753
+ console.error(err);
754
+ return;
755
+ }
756
+
757
+ console.log(content);
758
+ });
752
759
  </script>
753
760
  ```
754
761
 
@@ -761,16 +768,28 @@ You can mix rate limits and secured API keys by setting an extra `user_token` at
761
768
  public_key = Algolia.generate_secured_api_key 'YourRateLimitedApiKey', '(public,user_42)', 'user_42'
762
769
  ```
763
770
 
764
- This public API key must then be used in your JavaScript code as follow:
771
+ This public API key can then be used in your JavaScript code as follow:
765
772
 
766
773
  ```javascript
767
774
  <script type="text/javascript">
768
- var algolia = new AlgoliaSearch('YourApplicationID', '<%= public_api_key %>');
769
- algolia.setSecurityTags('(public,user_42)'); // must be same than those used at generation-time
770
- algolia.setUserToken('user_42') // must be same than the one used at generation-time
771
- algolia.initIndex('YourIndex').search($('#q').val(), function(success, content) {
772
- // [...]
773
- });
775
+ var client = algoliasearch('YourApplicationID', '<%= public_api_key %>');
776
+
777
+ // must be same than those used at generation-time
778
+ client.setSecurityTags('(public,user_42)');
779
+
780
+ // must be same than the one used at generation-time
781
+ client.setUserToken('user_42');
782
+
783
+ var index = client.initIndex('indexName')
784
+
785
+ index.search('another query', function(err, content) {
786
+ if (err) {
787
+ console.error(err);
788
+ return;
789
+ }
790
+
791
+ console.log(content);
792
+ });
774
793
  </script>
775
794
  ```
776
795
 
@@ -10,20 +10,26 @@ 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, :search_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, :batch_timeout
14
14
 
15
+ DEFAULT_CONNECT_TIMEOUT = 2
16
+ DEFAULT_RECEIVE_TIMEOUT = 30
17
+ DEFAULT_SEND_TIMEOUT = 30
18
+ DEFAULT_BATCH_TIMEOUT = 120
19
+ DEFAULT_SEARCH_TIMEOUT = 5
15
20
 
16
21
  def initialize(data = {})
17
22
  @ssl = data[:ssl].nil? ? true : data[:ssl]
18
23
  @ssl_version = data[:ssl_version].nil? ? nil : data[:ssl_version]
19
24
  @application_id = data[:application_id]
20
25
  @api_key = data[:api_key]
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)
23
- @connect_timeout = data[:connect_timeout]
24
- @send_timeout = data[:send_timeout]
25
- @receive_timeout = data[:receive_timeout]
26
- @search_timeout = data[:search_timeout]
26
+ @hosts = data[:hosts] || (["#{@application_id}.algolia.net"] + 1.upto(3).map { |i| "#{@application_id}-#{i}.algolianet.com" }.shuffle)
27
+ @search_hosts = data[:search_hosts] || data[:hosts] || (["#{@application_id}-dsn.algolia.net"] + 1.upto(3).map { |i| "#{@application_id}-#{i}.algolianet.com" }.shuffle)
28
+ @connect_timeout = data[:connect_timeout] || DEFAULT_CONNECT_TIMEOUT
29
+ @send_timeout = data[:send_timeout] || DEFAULT_SEND_TIMEOUT
30
+ @batch_timeout = data[:batch_timeout] || DEFAULT_BATCH_TIMEOUT
31
+ @receive_timeout = data[:receive_timeout] || DEFAULT_RECEIVE_TIMEOUT
32
+ @search_timeout = data[:search_timeout] || DEFAULT_SEARCH_TIMEOUT
27
33
  @headers = {
28
34
  Protocol::HEADER_API_KEY => api_key,
29
35
  Protocol::HEADER_APP_ID => application_id,
@@ -36,9 +42,26 @@ module Algolia
36
42
  # with common basic response handling. Will raise a
37
43
  # AlgoliaProtocolError if the response has an error status code,
38
44
  # and will return the parsed JSON body on success, if there is one.
39
- def request(uri, method, data = nil, timeout = nil, read = false)
45
+ def request(uri, method, data = nil, type = :write)
40
46
  exceptions = []
41
- thread_local_hosts(read, timeout).each do |host|
47
+
48
+ connect_timeout = @connect_timeout
49
+ send_timeout = if type == :search
50
+ @search_timeout
51
+ elsif type == :batch
52
+ type = :write
53
+ @batch_timeout
54
+ else
55
+ @send_timeout
56
+ end
57
+ receive_timeout = type == :search ? @search_timeout : @receive_timeout
58
+
59
+ (type == :write ? @hosts : @search_hosts).size.times do |i|
60
+ connect_timeout += 2 if i == 2
61
+ send_timeout += 10 if i == 2
62
+ receive_timeout += 10 if i == 2
63
+
64
+ host = thread_local_hosts(type != :write, connect_timeout, send_timeout, receive_timeout)[i]
42
65
  begin
43
66
  return perform_request(host[:session], host[:base_url] + uri, method, data)
44
67
  rescue AlgoliaProtocolError => e
@@ -51,20 +74,20 @@ module Algolia
51
74
  raise AlgoliaProtocolError.new(0, "Cannot reach any host: #{exceptions.map { |e| e.to_s }.join(', ')}")
52
75
  end
53
76
 
54
- def get(uri, timeout = nil, read = false)
55
- request(uri, :GET, nil, timeout, read)
77
+ def get(uri, type = :write)
78
+ request(uri, :GET, nil, type)
56
79
  end
57
80
 
58
- def post(uri, body = {}, timeout = nil, read = false)
59
- request(uri, :POST, body, timeout, read)
81
+ def post(uri, body = {}, type = :write)
82
+ request(uri, :POST, body, type)
60
83
  end
61
84
 
62
- def put(uri, body = {}, timeout = nil, read = false)
63
- request(uri, :PUT, body, timeout, read)
85
+ def put(uri, body = {}, type = :write)
86
+ request(uri, :PUT, body, type)
64
87
  end
65
88
 
66
- def delete(uri, timeout = nil, read = false)
67
- request(uri, :DELETE, nil, timeout, read)
89
+ def delete(uri, type = :write)
90
+ request(uri, :DELETE, nil, type)
68
91
  end
69
92
 
70
93
  private
@@ -75,10 +98,10 @@ module Algolia
75
98
  # if you change any of its attributes, we cannot change the timeout
76
99
  # of an HTTP session dynamically. That being said, having 1 pool per
77
100
  # timeout appears to be the only acceptable solution
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|
101
+ def thread_local_hosts(read, connect_timeout, send_timeout, receive_timeout)
102
+ thread_local_var = read ? :algolia_search_hosts : :algolia_hosts
103
+ Thread.current[thread_local_var] ||= {}
104
+ Thread.current[thread_local_var]["#{connect_timeout}-#{send_timeout}-#{receive_timeout}"] ||= (read ? search_hosts : hosts).map do |host|
82
105
  client = HTTPClient.new
83
106
  client.ssl_config.ssl_version = @ssl_version if @ssl && @ssl_version
84
107
  hinfo = {
@@ -86,13 +109,9 @@ module Algolia
86
109
  :session => client
87
110
  }
88
111
  hinfo[:session].transparent_gzip_decompression = true
89
- hinfo[:session].connect_timeout = @connect_timeout if @connect_timeout
90
- if forced_timeout
91
- hinfo[:session].send_timeout = hinfo[:session].receive_timeout = forced_timeout
92
- else
93
- hinfo[:session].send_timeout = @send_timeout if @send_timeout
94
- hinfo[:session].receive_timeout = @receive_timeout if @receive_timeout
95
- end
112
+ hinfo[:session].connect_timeout = connect_timeout
113
+ hinfo[:session].send_timeout = send_timeout
114
+ hinfo[:session].receive_timeout = receive_timeout
96
115
  hinfo[:session].ssl_config.add_trust_ca File.join(File.dirname(__FILE__), '..', '..', 'resources', 'ca-bundle.crt')
97
116
  hinfo
98
117
  end
@@ -210,7 +229,7 @@ module Algolia
210
229
  { :indexName => indexName, :params => Protocol.to_query(encoded_params) }
211
230
  end
212
231
  }
213
- Algolia.client.post(Protocol.multiple_queries_uri, requests.to_json, Algolia.client.search_timeout, true)
232
+ Algolia.client.post(Protocol.multiple_queries_uri, requests.to_json, :search)
214
233
  end
215
234
 
216
235
  #
@@ -220,7 +239,7 @@ module Algolia
220
239
  # {"name": "notes", "createdAt": "2013-01-18T15:33:13.556Z"}]}
221
240
  #
222
241
  def Algolia.list_indexes
223
- Algolia.client.get(Protocol.indexes_uri)
242
+ Algolia.client.get(Protocol.indexes_uri, :read)
224
243
  end
225
244
 
226
245
  #
@@ -296,12 +315,12 @@ module Algolia
296
315
 
297
316
  # List all existing user keys with their associated ACLs
298
317
  def Algolia.list_user_keys
299
- Algolia.client.get(Protocol.keys_uri)
318
+ Algolia.client.get(Protocol.keys_uri, :read)
300
319
  end
301
320
 
302
321
  # Get ACL of a user key
303
322
  def Algolia.get_user_key(key)
304
- Algolia.client.get(Protocol.key_uri(key))
323
+ Algolia.client.get(Protocol.key_uri(key), :read)
305
324
  end
306
325
 
307
326
  #
@@ -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, true)
139
+ Algolia.client.get(Protocol.search_uri(name, query, encoded_params), :search)
140
140
  end
141
141
 
142
142
  #
@@ -147,7 +147,7 @@ module Algolia
147
147
  # @param hitsPerPage: Pagination parameter used to select the number of hits per page. Defaults to 1000.
148
148
  #
149
149
  def browse(page = 0, hitsPerPage = 1000)
150
- Algolia.client.get(Protocol.browse_uri(name, {:page => page, :hitsPerPage => hitsPerPage}))
150
+ Algolia.client.get(Protocol.browse_uri(name, {:page => page, :hitsPerPage => hitsPerPage}), :read)
151
151
  end
152
152
 
153
153
  #
@@ -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), Algolia.client.search_timeout, true)
161
+ Algolia.client.get(Protocol.object_uri(name, objectID, nil), :read)
162
162
  else
163
- Algolia.client.get(Protocol.object_uri(name, objectID, {:attributes => attributesToRetrieve}), Algolia.client.search_timeout, true)
163
+ Algolia.client.get(Protocol.object_uri(name, objectID, {:attributes => attributesToRetrieve}), :read)
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, Algolia.client.search_timeout, true)['results']
173
+ Algolia.client.post(Protocol.objects_uri, { :requests => objectIDs.map { |objectID| { :indexName => name, :objectID => objectID } } }.to_json, :read)['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), nil, true)["status"]
184
+ status = Algolia.client.get(Protocol.task_uri(name, taskID), :read)["status"]
185
185
  if status == "published"
186
186
  return
187
187
  end
@@ -416,17 +416,17 @@ module Algolia
416
416
 
417
417
  # Get settings of this index
418
418
  def get_settings
419
- Algolia.client.get(Protocol.settings_uri(name))
419
+ Algolia.client.get(Protocol.settings_uri(name), :read)
420
420
  end
421
421
 
422
422
  # List all existing user keys with their associated ACLs
423
423
  def list_user_keys
424
- Algolia.client.get(Protocol.index_keys_uri(name))
424
+ Algolia.client.get(Protocol.index_keys_uri(name), :read)
425
425
  end
426
426
 
427
427
  # Get ACL of a user key
428
428
  def get_user_key(key)
429
- Algolia.client.get(Protocol.index_key_uri(name, key))
429
+ Algolia.client.get(Protocol.index_key_uri(name, key), :read)
430
430
  end
431
431
 
432
432
  #
@@ -473,7 +473,7 @@ module Algolia
473
473
 
474
474
  # Send a batch request
475
475
  def batch(request)
476
- Algolia.client.post(Protocol.batch_uri(name), request.to_json)
476
+ Algolia.client.post(Protocol.batch_uri(name), request.to_json, :batch)
477
477
  end
478
478
 
479
479
  # Send a batch request and wait the end of the indexing
@@ -1,3 +1,3 @@
1
1
  module Algolia
2
- VERSION = "1.4.0"
2
+ VERSION = "1.4.1"
3
3
  end
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.4.0
4
+ version: 1.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Algolia
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-17 00:00:00.000000000 Z
11
+ date: 2015-04-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httpclient