couchrest 2.0.0 → 2.0.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: 35f90529f40322cb4c79feff70763d46e7feb0b0
4
- data.tar.gz: 9cb8ed603d0898f37d1ebafeb23fa00204eaea62
3
+ metadata.gz: 75e93448320a86ecbcffd644ccb8afec72fdebf5
4
+ data.tar.gz: c5ca7599c73e5d86978bc0093e8758864a27a8eb
5
5
  SHA512:
6
- metadata.gz: e927060a2d0c42fd94f761b7f4f161c6627738c92c51de6bf483b9ebbce3527ab165420eb54a3a1c0e9f447d8f1cfc3323b70a05e87a761bac387472bd8c3b3e
7
- data.tar.gz: 431046aa57a718f9c2d9a1c966cf060b1123f49dff147ccd8a272b39ab1df5c59d8c038dc41c8d5f9cb6f84783c21e8c6abd380fbcca00b6999d5bee8754b460
6
+ metadata.gz: 3b025c928830967082f72203b020f303d794b5aca324c4e6acf3e4f353a7492ba975bae5d02f34f99aff6d59d0f91a137ec941ac3a09d05eb7a5dcca3ae13178
7
+ data.tar.gz: b2a1e1e2b507937ea8ccfa05a618a8e753ade2bda33a027ee817dfbae24b5256df93826f335132984d1f5350601f9d7140a8c8c9dcf8efcfb286477391e3ac49
@@ -3,10 +3,13 @@ rvm:
3
3
  - 2.2.0
4
4
  - 2.1.0
5
5
  - 2.0.0
6
- - jruby
6
+ - jruby-1.7.26
7
7
  - rbx
8
8
  services: couchdb
9
9
  before_install:
10
10
  - gem install bundler
11
11
  env:
12
12
  - JRUBY_OPTS=--2.0
13
+ matrix:
14
+ allow_failures:
15
+ - rvm: rbx
data/README.md CHANGED
@@ -12,6 +12,14 @@ For more complete modelling support based on ActiveModel, please checkout CouchR
12
12
 
13
13
  Tested on latest stable release (1.6.X), but should work on older versions above 1.0. Also known to work on [Cloudant](http://cloudant.com).
14
14
 
15
+ ### Performance with Persistent Connections
16
+
17
+ When connecting to a CouchDB 1.X server from a Linux system, you may see a big drop in performance due to the change in library to HTTPClient using persistent connections. The issue is caused by the NOWAIT TCP configuration option causing sockets to hang as they wait for more information. The fix is a [simple configuration change](http://docs.couchdb.org/en/1.6.1/maintenance/performance.html#network):
18
+
19
+ ```bash
20
+ curl -X PUT "http://localhost:5984/_config/httpd/socket_options" -d '"[{nodelay, true}]"'
21
+ ```
22
+
15
23
  ## Install
16
24
 
17
25
  $ sudo gem install couchrest
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.0.0
1
+ 2.0.1
@@ -34,6 +34,6 @@ Gem::Specification.new do |s|
34
34
  s.add_development_dependency "bundler", "~> 1.3"
35
35
  # s.add_development_dependency "json", ">= 2.0.1"
36
36
  s.add_development_dependency "rspec", "~> 2.14.1"
37
- s.add_development_dependency "rake"
37
+ s.add_development_dependency "rake", "< 11.0"
38
38
  s.add_development_dependency "webmock"
39
39
  end
@@ -1,3 +1,11 @@
1
+ == 2.0.1 - 2017-02-13
2
+
3
+ * Minor changes
4
+ * Removing option for persistent connections, everything is now persistent
5
+ (@samlown)
6
+ * Simplifying connection handling and thread safety. Removed caching and lazy
7
+ loading of connections. (@samlown)
8
+
1
9
  == 2.0.0 - 2016-07-06
2
10
 
3
11
  * Minor changes
@@ -5,7 +5,7 @@ module CouchRest
5
5
  # Handle connections to the CouchDB server and provide a set of HTTP based methods to
6
6
  # perform requests.
7
7
  #
8
- # All connections are persistent, unless configured otherwise. A connection cannot be re-used to connect to other servers.
8
+ # All connections are persistent and thread safe. A connection cannot be re-used to connect to other servers once instantiated.
9
9
  #
10
10
  # Six types of REST requests are supported: get, put, post, delete, copy and head.
11
11
  #
@@ -16,7 +16,6 @@ module CouchRest
16
16
  #
17
17
  # When initializing a connection, the following options are available:
18
18
  #
19
- # * `:persistent` true by default, forces the HTTP connection to be persistent to ensure each request attempts to use the same TCP socket, especially important for SSL connections.
20
19
  # * `:timeout` (or `:read_timeout`) and `:open_timeout` the time in miliseconds to wait for the request, see the [Net HTTP Persistent documentation](http://docs.seattlerb.org/net-http-persistent/Net/HTTP/Persistent.html#attribute-i-read_timeout) for more details.
21
20
  # * `:verify_ssl` verify ssl certificates (or not)
22
21
  # * `:ssl_client_cert`, `:ssl_client_key` parameters controlling ssl client certificate authentication
@@ -54,13 +53,13 @@ module CouchRest
54
53
 
55
54
  SUCCESS_RESPONSE_CODES = [200, 201, 202, 204]
56
55
 
57
- attr_reader :uri, :last_response, :options
56
+ attr_reader :uri, :last_response, :options, :http
58
57
 
59
58
  def initialize(uri, options = {})
60
59
  raise "CouchRest::Connection.new requires URI::HTTP(S) parameter" unless uri.is_a?(URI::HTTP)
61
60
  @uri = clean_uri(uri)
62
61
  @options = options.dup
63
- @options[:persistent] = true if @options[:persistent].nil?
62
+ @http = prepare_http_connection
64
63
  end
65
64
 
66
65
  # Send a GET request.
@@ -97,13 +96,7 @@ module CouchRest
97
96
  execute('HEAD', path, options)
98
97
  end
99
98
 
100
- # Special accessor that will either return the last used http
101
- # connection or prepare a new one if none available.
102
- def http
103
- @http || prepare_http_connection
104
- end
105
-
106
- protected
99
+ private
107
100
 
108
101
  # Duplicate and remove excess baggage from the provided URI
109
102
  def clean_uri(uri)
@@ -116,12 +109,8 @@ module CouchRest
116
109
 
117
110
  # Take a look at the options povided and try to apply them to the HTTP conneciton.
118
111
  def prepare_http_connection
119
- conn = @http
120
- if conn.nil? || !options[:persistent]
121
- conn = HTTPClient.new(options[:proxy] || self.class.proxy)
122
- set_http_connection_options(conn, options)
123
- @http = conn # Always set to last used connection
124
- end
112
+ conn = HTTPClient.new(options[:proxy] || self.class.proxy)
113
+ set_http_connection_options(conn, options)
125
114
  conn
126
115
  end
127
116
 
@@ -149,8 +138,6 @@ module CouchRest
149
138
  end
150
139
 
151
140
  def execute(method, path, options, payload = nil, &block)
152
- conn = prepare_http_connection
153
-
154
141
  req = {
155
142
  :method => method,
156
143
  :uri => uri + path
@@ -167,13 +154,13 @@ module CouchRest
167
154
  req[:body] = payload_from_doc(req, payload, options)
168
155
  end
169
156
 
170
- send_and_parse_response(conn, req, options, &block)
157
+ send_and_parse_response(req, options, &block)
171
158
  end
172
159
 
173
- def send_and_parse_response(conn, req, opts, &block)
160
+ def send_and_parse_response(req, opts, &block)
174
161
  if block_given?
175
162
  parser = CouchRest::StreamRowParser.new(opts[:continuous] ? :feed : :array)
176
- response = send_request(conn, req) do |chunk|
163
+ response = send_request(req) do |chunk|
177
164
  parser.parse(chunk) do |doc|
178
165
  block.call(parse_body(doc, opts))
179
166
  end
@@ -181,15 +168,15 @@ module CouchRest
181
168
  handle_response_code(response)
182
169
  parse_body(parser.header, opts)
183
170
  else
184
- response = send_request(conn, req)
171
+ response = send_request(req)
185
172
  handle_response_code(response)
186
173
  parse_response(response, opts)
187
174
  end
188
175
  end
189
176
 
190
177
  # Send request, and leave a reference to the response for debugging purposes
191
- def send_request(conn, req, &block)
192
- @last_response = conn.request(req.delete(:method), req.delete(:uri), req, &block)
178
+ def send_request(req, &block)
179
+ @last_response = @http.request(req.delete(:method), req.delete(:uri), req, &block)
193
180
  end
194
181
 
195
182
  def handle_response_code(response)
@@ -12,6 +12,9 @@ module CouchRest
12
12
  # saving new documents. See also #next_uuid.
13
13
  attr_reader :uuids
14
14
 
15
+ # Connection object prepared on initialization
16
+ attr_reader :connection
17
+
15
18
  # The connection options we should use to connect with
16
19
  attr_reader :connection_options
17
20
 
@@ -26,13 +29,7 @@ module CouchRest
26
29
  @connection_options = opts
27
30
  end
28
31
  @uuid_batch_count ||= 1000
29
- end
30
-
31
- # Lazy load the connection for the current thread
32
- def connection
33
- conns = (Thread.current['couchrest.connections'] ||= {})
34
- key = "#{uri.to_s}##{connection_options.hash}"
35
- conns[key] ||= Connection.new(uri, connection_options)
32
+ @connection = Connection.new(uri, connection_options)
36
33
  end
37
34
 
38
35
  # Lists all databases on the server
@@ -172,29 +172,6 @@ describe CouchRest::Connection do
172
172
  expect(res['name']).to eql(doc['name'])
173
173
  end
174
174
 
175
- context "persistency" do
176
- before :each do
177
- stub_request(:get, "http://mock/db/test-doc")
178
- .to_return(:body => doc.to_json)
179
- end
180
-
181
- it "should have persistency enabled by default" do
182
- conn = CouchRest::Connection.new(mock_uri)
183
- expect(conn.options[:persistent]).to be_true
184
- http1 = conn.http
185
- conn.get(mock_uri.path)
186
- expect(conn.http.object_id).to eql(http1.object_id)
187
- end
188
-
189
- it "should disable persistency" do
190
- conn = CouchRest::Connection.new(mock_uri, :persistent => false)
191
- expect(conn.options[:persistent]).to be_false
192
- http1 = conn.http
193
- conn.get(mock_uri.path)
194
- expect(conn.http.object_id).to_not eql(http1.object_id)
195
- end
196
- end
197
-
198
175
  it "should raise exception if document missing" do
199
176
  uri = URI(DB.to_s + "/missingdoc")
200
177
  conn = CouchRest::Connection.new(uri)
@@ -209,7 +209,7 @@ describe CouchRest::Database do
209
209
  end
210
210
  rescue RuntimeError
211
211
  end
212
- expect(changes.first["seq"]).to eql(1)
212
+ expect(changes.first["seq"].to_i).to eql(1)
213
213
  end
214
214
 
215
215
  it "should provide id of last document" do
@@ -51,35 +51,18 @@ describe CouchRest::Server do
51
51
  expect(server.connection).to be_a(CouchRest::Connection)
52
52
  end
53
53
 
54
- it "should cache connection in current thread" do
55
- server.connection # instantiate
56
- conns = Thread.current['couchrest.connections']
57
- expect(server.connection).to eql(conns[COUCHHOST + "##{{}.hash}"])
58
- end
59
-
60
- it "should cache connection in current thread with options" do
61
- Thread.current['couchrest.connections'] = {}
62
- srv = CouchRest::Server.new(mock_url, :persistent => false)
63
- srv.connection # instantiate
64
- conns = Thread.current['couchrest.connections']
65
- expect(srv.connection.object_id).to eql(conns[conns.keys.last].object_id)
66
- expect(conns.length).to eql(1)
67
- end
68
-
69
- it "should not cache connection in current thread with different options" do
70
- conns = Thread.current['couchrest.connections'] = {}
71
- srv = CouchRest::Server.new(mock_url, :persistent => true)
72
- srv.connection # init
73
- srv2 = CouchRest::Server.new(mock_url, :persistent => false)
74
- srv2.connection # init
75
- expect(conns.length).to eql(2)
76
- expect(srv.connection.object_id).to_not eql(srv2.connection.object_id)
54
+ it "should be shared by all threads" do
55
+ conn = server.connection
56
+ conn2 = nil
57
+ Thread.new {
58
+ conn2 = server.connection
59
+ }.join
60
+ expect(conn.object_id).to eql(conn2.object_id)
77
61
  end
78
62
 
79
63
  it "should pass configuration options to the connection" do
80
- expect(mock_server.connection.options[:persistent]).to be_true
81
- srv = CouchRest::Server.new(mock_url, :persistent => false)
82
- expect(srv.connection.options[:persistent]).to be_false
64
+ srv = CouchRest::Server.new(mock_url, :timeout => 120)
65
+ expect(srv.connection.options[:timeout]).to eql(120)
83
66
  end
84
67
 
85
68
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: couchrest
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - J. Chris Anderson
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2016-07-06 00:00:00.000000000 Z
15
+ date: 2017-02-13 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: httpclient
@@ -88,16 +88,16 @@ dependencies:
88
88
  name: rake
89
89
  requirement: !ruby/object:Gem::Requirement
90
90
  requirements:
91
- - - ">="
91
+ - - "<"
92
92
  - !ruby/object:Gem::Version
93
- version: '0'
93
+ version: '11.0'
94
94
  type: :development
95
95
  prerelease: false
96
96
  version_requirements: !ruby/object:Gem::Requirement
97
97
  requirements:
98
- - - ">="
98
+ - - "<"
99
99
  - !ruby/object:Gem::Version
100
- version: '0'
100
+ version: '11.0'
101
101
  - !ruby/object:Gem::Dependency
102
102
  name: webmock
103
103
  requirement: !ruby/object:Gem::Requirement
@@ -206,7 +206,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
206
206
  version: 1.3.1
207
207
  requirements: []
208
208
  rubyforge_project:
209
- rubygems_version: 2.4.6
209
+ rubygems_version: 2.6.8
210
210
  signing_key:
211
211
  specification_version: 4
212
212
  summary: Lean and RESTful interface to CouchDB.