noiseless 0.4.0 → 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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a2c76e38f11ce0e3d82ecea5c3644022e1b793613e413f81987063e333da393
4
- data.tar.gz: 7b862a6892326ed2fff34d3aa087d2cdfeafbc1b007b5f5c6285286d12d26a4f
3
+ metadata.gz: 466267a77224bbf9915eff8b198002c658e2e9c9d368c6c7f6e4e4ee32939892
4
+ data.tar.gz: 71281cfbbcdd40f83f55eedb0fca494f1e0a75172c4a9523c3000cae81fa752d
5
5
  SHA512:
6
- metadata.gz: d25d6a3a8fd986c7f99454f358da6abe29a7c64ee4beddab5925a83c580469625dfc20bf6b19e6ca6af0448ea87093d05275b24ef23d7b4b9b17edc93ceec9a4
7
- data.tar.gz: 61371d2765af21a3d689931abe71afe4b13942fe4b6c7621115b0d75b1ce0a4d249b28f7ffb40a66e1ab28d5da57f65d3d8814e62372bd13c05c74885cd26507
6
+ metadata.gz: 7a0a6c9aa9134b043b4a87c8434735f837bca7cfc63520693e3bf49ff4001617351cf92259b73a781187fd22812d65f781130570f753d27dd68d4d6f3bb16fd0
7
+ data.tar.gz: 14387643b5a8c5b5fc506e00b28b8d5b2664d359bd48797c6180df38f03efa370dd86d46d0a871194328ff80f487458e439733b250dfdad9cf369a253e069c3e
@@ -14,17 +14,35 @@ module Noiseless
14
14
  # DNS failure, transport timeout). These are wrapped into
15
15
  # Noiseless::ConnectionError so callers never have to know which HTTP
16
16
  # stack is underneath.
17
- TRANSPORT_ERRORS = [SystemCallError, SocketError, IOError, Timeout::Error].freeze
18
- def initialize(hosts: [], **connection_params)
17
+ TRANSPORT_ERRORS = [
18
+ SystemCallError,
19
+ SocketError,
20
+ IOError,
21
+ IO::TimeoutError,
22
+ Timeout::Error
23
+ ].freeze
24
+
25
+ # Default per-operation IO timeout (seconds) for the search backend.
26
+ # This is an *idle* timeout: every socket read/write must make progress
27
+ # within this window. It bounds a stalled/unresponsive backend without
28
+ # capping the total duration of streaming operations (e.g. bulk import),
29
+ # since data keeps flowing during those. Override per-connection with
30
+ # +timeout:+.
31
+ DEFAULT_TIMEOUT = 5
32
+
33
+ def initialize(hosts: [], timeout: DEFAULT_TIMEOUT, **connection_params)
19
34
  # Ensure we always have at least one host
20
35
  hosts_array = Array(hosts)
21
36
  @hosts = hosts_array.empty? ? ["http://localhost:#{default_port}"] : hosts_array
37
+ @timeout = timeout
22
38
  @connection_params = connection_params
23
39
 
24
- # Initialize HTTP clients for each host
40
+ # Initialize HTTP clients for each host. The endpoint timeout makes a
41
+ # stalled backend raise IO::TimeoutError (wrapped below as
42
+ # ConnectionError) instead of blocking the fiber/reactor indefinitely.
25
43
  @clients = {}
26
44
  @hosts.each do |host|
27
- endpoint = Async::HTTP::Endpoint.parse(host)
45
+ endpoint = Async::HTTP::Endpoint.parse(host, timeout: @timeout)
28
46
  @clients[host] = Async::HTTP::Client.new(endpoint)
29
47
  end
30
48
 
@@ -77,10 +95,19 @@ module Noiseless
77
95
  host = @hosts.sample
78
96
  client = @clients[host]
79
97
 
80
- yield(client)
98
+ wrap_transport_errors(host: host) { yield(client) }
99
+ end
100
+
101
+ def parse_json_response!(response, error_class: Noiseless::RequestError, context: nil)
102
+ wrap_transport_errors { super }
103
+ end
104
+
105
+ def wrap_transport_errors(host: nil)
106
+ yield
81
107
  rescue *TRANSPORT_ERRORS => e
108
+ location = host ? " at #{host}" : ""
82
109
  raise Noiseless::ConnectionError,
83
- "search backend unreachable at #{host} (#{e.class}: #{e.message})"
110
+ "search backend unreachable#{location} (#{e.class}: #{e.message})"
84
111
  end
85
112
 
86
113
  def default_headers
@@ -8,8 +8,8 @@ module Noiseless
8
8
  end
9
9
 
10
10
  # Register a named client statically from YAML (boot-time only)
11
- def register(name, adapter:, hosts:)
12
- @configs[name.to_sym] = { adapter: adapter, hosts: hosts }
11
+ def register(name, adapter:, hosts:, timeout: nil)
12
+ @configs[name.to_sym] = { adapter: adapter, hosts: hosts, timeout: timeout }
13
13
  end
14
14
 
15
15
  # Retrieve a client; defaults to :primary
@@ -19,7 +19,9 @@ module Noiseless
19
19
  # Lazy-load the adapter only when actually used
20
20
  @clients[name] ||= begin
21
21
  config = @configs.fetch(name) { raise "Unknown connection: #{name}" }
22
- Adapters.lookup(config[:adapter], hosts: config[:hosts])
22
+ params = { hosts: config[:hosts] }
23
+ params[:timeout] = config[:timeout] unless config[:timeout].nil?
24
+ Adapters.lookup(config[:adapter], **params)
23
25
  end
24
26
  end
25
27
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Noiseless
4
- VERSION = "0.4.0"
4
+ VERSION = "0.5.0"
5
5
  end
data/lib/noiseless.rb CHANGED
@@ -93,7 +93,7 @@ module Noiseless
93
93
  config.connections_config.each do |name, params|
94
94
  adapter_name = params[:adapter]
95
95
  hosts = params[:hosts] || []
96
- connections.register(name, adapter: adapter_name, hosts: hosts)
96
+ connections.register(name, adapter: adapter_name, hosts: hosts, timeout: params[:timeout])
97
97
  end
98
98
  end
99
99
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: noiseless
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Abdelkader Boudih