cassandra-driver 1.0.0.rc.1 → 1.0.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 +8 -8
- data/README.md +45 -10
- data/lib/cassandra.rb +82 -82
- data/lib/cassandra/cluster.rb +3 -0
- data/lib/cassandra/cluster/client.rb +17 -5
- data/lib/cassandra/{client/connection_manager.rb → cluster/connection_pool.rb} +3 -3
- data/lib/cassandra/cluster/connector.rb +101 -30
- data/lib/cassandra/cluster/control_connection.rb +6 -7
- data/lib/cassandra/{client/null_logger.rb → cluster/failed_connection.rb} +12 -14
- data/lib/cassandra/cluster/options.rb +8 -0
- data/lib/cassandra/column.rb +5 -0
- data/lib/cassandra/driver.rb +3 -3
- data/lib/cassandra/errors.rb +5 -5
- data/lib/cassandra/execution/options.rb +13 -6
- data/lib/cassandra/execution/trace.rb +4 -4
- data/lib/cassandra/future.rb +4 -0
- data/lib/cassandra/keyspace.rb +5 -0
- data/lib/cassandra/load_balancing/policies/dc_aware_round_robin.rb +7 -2
- data/lib/cassandra/load_balancing/policies/token_aware.rb +1 -3
- data/lib/cassandra/load_balancing/policies/white_list.rb +3 -6
- data/lib/cassandra/null_logger.rb +35 -0
- data/lib/cassandra/protocol/cql_protocol_handler.rb +4 -0
- data/lib/cassandra/protocol/requests/query_request.rb +1 -11
- data/lib/cassandra/result.rb +4 -6
- data/lib/cassandra/session.rb +3 -0
- data/lib/cassandra/statements/prepared.rb +5 -1
- data/lib/cassandra/table.rb +5 -0
- data/lib/cassandra/util.rb +130 -0
- data/lib/cassandra/version.rb +1 -1
- metadata +9 -20
- data/lib/cassandra/client.rb +0 -144
- data/lib/cassandra/client/batch.rb +0 -212
- data/lib/cassandra/client/client.rb +0 -591
- data/lib/cassandra/client/column_metadata.rb +0 -54
- data/lib/cassandra/client/connector.rb +0 -273
- data/lib/cassandra/client/execute_options_decoder.rb +0 -59
- data/lib/cassandra/client/peer_discovery.rb +0 -50
- data/lib/cassandra/client/prepared_statement.rb +0 -314
- data/lib/cassandra/client/query_result.rb +0 -230
- data/lib/cassandra/client/request_runner.rb +0 -70
- data/lib/cassandra/client/result_metadata.rb +0 -48
- data/lib/cassandra/client/void_result.rb +0 -78
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
OTcyZDFmZGEzMGZhODU2MTRkYmRlMjhiNWIyYWI0OWVkODZmYmY3Mg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MzQ5Y2M4YmI1YzQ3Yjk3MDU4YzI1YWJjYmZjYTc2YTE4NjA4ZTRmMQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
NmFiNzc1M2E0NTk0YmIyY2VjNTcxZjI2ZDcwMGE5NmUzZDhhZGU5NmYyMTRj
|
10
|
+
M2NiZjgwNzdmMzJjOTA4YzBjNjVlYjRlNmJmZjE3MjZhOWY1ODRlOTQwM2Qy
|
11
|
+
YzYyNzc2MTFmYzNjOWNiZmI4NjY3Yjg4ZjBjYjJkMWRmMTY2Mzg=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
M2EzNzFhZDM5MTNkMTlhNzVhZTE1YzdmZGMyMWEyY2ZmZTc4N2YwMGIwMjll
|
14
|
+
ODhkNzFjODE3NmMxYTE5Y2U4MzA0ZjViMTQ3MzYyMjcwZDJkNjgyZjg1Y2Q2
|
15
|
+
NWY3MjRjM2QwY2VhMTU4MGIzOWM0YmY2MjI4ZmYyOTdhMDU0NDE=
|
data/README.md
CHANGED
@@ -9,10 +9,10 @@ the Cassandra Query Language version 3 (CQL3) and Cassandra's native protocol.
|
|
9
9
|
|
10
10
|
- Code: https://github.com/datastax/ruby-driver
|
11
11
|
- Docs: http://datastax.github.io/ruby-driver/
|
12
|
-
-
|
13
|
-
-
|
12
|
+
- Jira: https://datastax-oss.atlassian.net/browse/RUBY
|
13
|
+
- Mailing List: https://groups.google.com/a/lists.datastax.com/forum/#!forum/ruby-driver-user
|
14
14
|
- IRC: #datastax-drivers on [irc.freenode.net](http://freenode.net>)
|
15
|
-
-
|
15
|
+
- Twitter: Follow the latest news about DataStax Drivers - [@avalanche123](http://twitter.com/avalanche123), [@mfiguiere](http://twitter.com/mfiguiere), [@al3xandru](https://twitter.com/al3xandru)
|
16
16
|
|
17
17
|
This driver is based on [the cql-rb gem](https://github.com/iconara/cql-rb) by [Theo Hultberg](https://github.com/iconara) and we added support for:
|
18
18
|
|
@@ -26,10 +26,11 @@ This driver is based on [the cql-rb gem](https://github.com/iconara/cql-rb) by [
|
|
26
26
|
|
27
27
|
This driver works exclusively with the Cassandra Query Language v3 (CQL3) and Cassandra's native protocol. The current version works with:
|
28
28
|
|
29
|
-
* Cassandra versions 1.2 and 2.0
|
30
|
-
*
|
29
|
+
* Apache Cassandra versions 1.2 and 2.0
|
30
|
+
* DataStax Enterprise 3.1, 3.2, 4.0 and 4.5
|
31
|
+
* Ruby (MRI) 1.9.3, 2.0 and 2.1
|
31
32
|
* JRuby 1.7
|
32
|
-
* Rubinius 2.
|
33
|
+
* Rubinius 2.2
|
33
34
|
|
34
35
|
__Note__: JRuby 1.6 is not officially supported, although 1.6.8 should work.
|
35
36
|
|
@@ -75,7 +76,7 @@ gem install cassandra-driver --pre
|
|
75
76
|
Install via Gemfile
|
76
77
|
|
77
78
|
```ruby
|
78
|
-
gem 'cassandra-driver', '~> 1.0.0.
|
79
|
+
gem 'cassandra-driver', '~> 1.0.0.rc'
|
79
80
|
```
|
80
81
|
|
81
82
|
Note: if you want to use compression you should also install [snappy](http://rubygems.org/gems/snappy) or [lz4-ruby](http://rubygems.org/gems/lz4-ruby). [Read more about compression.](http://datastax.github.io/ruby-driver/features/#compression)
|
@@ -85,13 +86,45 @@ Note: if you want to use compression you should also install [snappy](http://rub
|
|
85
86
|
|
86
87
|
Some of the new features added to the driver have unfortunately led to changes in the original cql-rb API. In the examples directory, you can find [an example of how to wrap the ruby driver to achieve almost complete interface parity with cql-rb](https://github.com/datastax/ruby-driver/blob/master/examples/cql-rb-wrapper.rb) to assist you with gradual upgrade.
|
87
88
|
|
88
|
-
## What's new in v1.0.0
|
89
|
+
## What's new in v1.0.0
|
89
90
|
|
90
91
|
Current release introduces the following new features:
|
91
92
|
|
92
|
-
* [
|
93
|
+
* [Asynchronous execution](http://datastax.github.io/ruby-driver/features/asynchronous_io/)
|
94
|
+
* One-off, [prepared](http://datastax.github.io/ruby-driver/features/basics/prepared_statements/) and [batch statements](http://datastax.github.io/ruby-driver/features/basics/batch_statements/)
|
95
|
+
* Automatic peer discovery and cluster metadata with [support for change notifications](http://datastax.github.io/ruby-driver/features/state_listeners/)
|
96
|
+
* Various [load-balancing](http://datastax.github.io/ruby-driver/features/load_balancing/), [retry](http://datastax.github.io/ruby-driver/features/retry_policies/) and reconnection policies, [with ability to write your own](http://datastax.github.io/ruby-driver/features/load_balancing/implementing_a_policy/)
|
93
97
|
* [SSL encryption](http://datastax.github.io/ruby-driver/features/security/ssl_encryption/)
|
94
|
-
*
|
98
|
+
* [Flexible and robust error handling](http://datastax.github.io/ruby-driver/features/error_handling/)
|
99
|
+
* [Per-request execution information and tracing](http://datastax.github.io/ruby-driver/features/debugging/)
|
100
|
+
* [Configurable address resolution](http://datastax.github.io/ruby-driver/features/address_resolution/)
|
101
|
+
|
102
|
+
## Code examples
|
103
|
+
|
104
|
+
The DataStax Ruby Driver uses the awesome [Cucumber Framework](http://cukes.info/) for both end-to-end, or acceptance, testing and constructing documentation. All of the features supported by the driver have appropriate acceptance tests with easy-to-copy code examples in the `features/` directory.
|
105
|
+
|
106
|
+
## Running tests
|
107
|
+
|
108
|
+
If you don't feel like reading through the following instructions on how to run ruby-driver tests, feel free to [check out .travis.yml for the entire build code](https://github.com/datastax/ruby-driver/blob/master/.travis.yml).
|
109
|
+
|
110
|
+
* Check out the driver codebase and install test dependencies:
|
111
|
+
|
112
|
+
```bash
|
113
|
+
git clone https://github.com/datastax/ruby-driver.git
|
114
|
+
cd ruby-driver
|
115
|
+
bundle install --without docs
|
116
|
+
```
|
117
|
+
|
118
|
+
* [Install ccm](http://www.datastax.com/dev/blog/ccm-a-development-tool-for-creating-local-cassandra-clusters)
|
119
|
+
|
120
|
+
* Run tests:
|
121
|
+
|
122
|
+
```bash
|
123
|
+
bundle exec cucumber # runs end-to-end tests (or bundle exec rake cucumber)
|
124
|
+
bundle exec rspec # runs unit tests (or bundle exec rake rspec)
|
125
|
+
bundle exec rake integration # run integration tests
|
126
|
+
bundle exec rake test # run both as well as integration tests
|
127
|
+
```
|
95
128
|
|
96
129
|
## Changelog & versioning
|
97
130
|
|
@@ -105,7 +138,9 @@ Prereleases will be stable, in the sense that they will have finished and proper
|
|
105
138
|
|
106
139
|
* JRuby 1.6 is not officially supported, although 1.6.8 should work, if you're stuck in JRuby 1.6.8 try and see if it works for you.
|
107
140
|
* Because the driver reactor is using `IO.select`, the maximum number of tcp connections allowed is 1024.
|
141
|
+
* Because the driver uses `IO#write_nonblock`, Windows is not supported.
|
108
142
|
|
143
|
+
Please [refer to the usage documentation for more information on common pitfalls](http://datastax.github.io/ruby-driver/features/)
|
109
144
|
|
110
145
|
## Credits
|
111
146
|
|
data/lib/cassandra.rb
CHANGED
@@ -66,21 +66,22 @@ module Cassandra
|
|
66
66
|
# in `:hosts` option.
|
67
67
|
#
|
68
68
|
# @option options [Numeric] :connect_timeout (10) connection timeout in
|
69
|
-
# seconds.
|
69
|
+
# seconds. Setting value to `nil` will reset it to 5 seconds.
|
70
70
|
#
|
71
71
|
# @option options [Numeric] :timeout (10) request execution timeout in
|
72
|
-
# seconds.
|
72
|
+
# seconds. Setting value to `nil` will remove request timeout.
|
73
73
|
#
|
74
74
|
# @option options [Numeric] :heartbeat_interval (30) how often should a
|
75
75
|
# heartbeat be sent to determine if a connection is alive. Several things to
|
76
76
|
# note about this option. Only one heartbeat request will ever be
|
77
77
|
# outstanding on a given connection. Each heatbeat will be sent in at least
|
78
78
|
# `:heartbeat_interval` seconds after the last request has been sent on a
|
79
|
-
# given connection.
|
79
|
+
# given connection. Setting value to `nil` will remove connection timeout.
|
80
80
|
#
|
81
81
|
# @option options [Numeric] :idle_timeout (60) period of inactivity after
|
82
82
|
# which a connection is considered dead. Note that this value should be at
|
83
|
-
# least a few times larger than `:heartbeat_interval`.
|
83
|
+
# least a few times larger than `:heartbeat_interval`. Setting value to
|
84
|
+
# `nil` will remove automatic connection termination.
|
84
85
|
#
|
85
86
|
# @option options [String] :username (none) username to use for
|
86
87
|
# authentication to cassandra. Note that you must also specify `:password`.
|
@@ -139,15 +140,15 @@ module Cassandra
|
|
139
140
|
# @option options [Boolean] :trace (false) whether or not to trace all
|
140
141
|
# requests by default.
|
141
142
|
#
|
142
|
-
# @option options [Integer] :page_size (
|
143
|
-
# queries.
|
143
|
+
# @option options [Integer] :page_size (10000) default page size for all
|
144
|
+
# select queries. Set this value to `nil` to disable paging.
|
144
145
|
#
|
145
146
|
# @option options [Hash{String => String}] :credentials (none) a hash of credentials - to be used with [credentials authentication in cassandra 1.2](https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v1.spec#L238-L250). Note that if you specified `:username` and `:password` options, those credentials are configured automatically.
|
146
147
|
#
|
147
148
|
# @option options [Cassandra::Auth::Provider] :auth_provider (none) a custom auth provider to be used with [SASL authentication in cassandra 2.0](https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v2.spec#L257-L273). Note that if you have specified `:username` and `:password`, then a {Cassandra::Auth::Providers::Password} will be used automatically.
|
148
149
|
#
|
149
|
-
# @option options [Cassandra::Compressor] :compressor (none) a
|
150
|
-
# compressor. Note that if you have specified `:compression`, an
|
150
|
+
# @option options [Cassandra::Compression::Compressor] :compressor (none) a
|
151
|
+
# custom compressor. Note that if you have specified `:compression`, an
|
151
152
|
# appropriate compressor will be provided automatically.
|
152
153
|
#
|
153
154
|
# @option options [Cassandra::AddressResolution::Policy]
|
@@ -157,10 +158,10 @@ module Cassandra
|
|
157
158
|
# appropriate address resolution policy will be provided automatically.
|
158
159
|
#
|
159
160
|
# @option options [Object<#all, #error, #value, #promise>] :futures_factory
|
160
|
-
#
|
161
|
-
# futures library. Note that promises returned by this object
|
162
|
-
# to {Cassandra::Promise} api, which is not yet public. Things
|
163
|
-
# use at your own risk.
|
161
|
+
# default: {Cassandra::Future} a futures factory to assist with integration
|
162
|
+
# into existing futures library. Note that promises returned by this object
|
163
|
+
# must conform to {Cassandra::Promise} api, which is not yet public. Things
|
164
|
+
# may change, use at your own risk.
|
164
165
|
#
|
165
166
|
# @example Connecting to localhost
|
166
167
|
# cluster = Cassandra.cluster
|
@@ -174,6 +175,16 @@ module Cassandra
|
|
174
175
|
#
|
175
176
|
# @return [Cassandra::Cluster] a cluster instance
|
176
177
|
def self.cluster(options = {})
|
178
|
+
cluster_async(options).get
|
179
|
+
end
|
180
|
+
|
181
|
+
# Creates a {Cassandra::Cluster} instance
|
182
|
+
#
|
183
|
+
# @see Cassandra.cluster
|
184
|
+
#
|
185
|
+
# @return [Cassandra::Future<Cassandra::Cluster>] a future resolving to the
|
186
|
+
# cluster instance.
|
187
|
+
def self.cluster_async(options = {})
|
177
188
|
options = options.select do |key, value|
|
178
189
|
[ :credentials, :auth_provider, :compression, :hosts, :logger, :port,
|
179
190
|
:load_balancing_policy, :reconnection_policy, :retry_policy, :listeners,
|
@@ -184,6 +195,8 @@ module Cassandra
|
|
184
195
|
].include?(key)
|
185
196
|
end
|
186
197
|
|
198
|
+
futures = options.fetch(:futures_factory, Future)
|
199
|
+
|
187
200
|
has_username = options.has_key?(:username)
|
188
201
|
has_password = options.has_key?(:password)
|
189
202
|
if has_username || has_password
|
@@ -195,11 +208,13 @@ module Cassandra
|
|
195
208
|
raise ::ArgumentError, "both :username and :password options must be specified, but only :password given"
|
196
209
|
end
|
197
210
|
|
198
|
-
username =
|
199
|
-
password =
|
211
|
+
username = options.delete(:username)
|
212
|
+
password = options.delete(:password)
|
200
213
|
|
201
|
-
|
202
|
-
|
214
|
+
Util.assert_instance_of(::String, username) { ":username must be a String, #{username.inspect} given" }
|
215
|
+
Util.assert_instance_of(::String, password) { ":password must be a String, #{password.inspect} given" }
|
216
|
+
Util.assert_not_empty(username) { ":username cannot be empty" }
|
217
|
+
Util.assert_not_empty(password) { ":password cannot be empty" }
|
203
218
|
|
204
219
|
options[:credentials] = {:username => username, :password => password}
|
205
220
|
options[:auth_provider] = Auth::Providers::Password.new(username, password)
|
@@ -208,17 +223,13 @@ module Cassandra
|
|
208
223
|
if options.has_key?(:credentials)
|
209
224
|
credentials = options[:credentials]
|
210
225
|
|
211
|
-
|
212
|
-
raise ::ArgumentError, ":credentials must be a hash, #{credentials.inspect} given"
|
213
|
-
end
|
226
|
+
Util.assert_instance_of(::Hash, credentials) { ":credentials must be a hash, #{credentials.inspect} given" }
|
214
227
|
end
|
215
228
|
|
216
229
|
if options.has_key?(:auth_provider)
|
217
230
|
auth_provider = options[:auth_provider]
|
218
231
|
|
219
|
-
|
220
|
-
raise ::ArgumentError, ":auth_provider #{auth_provider.inspect} must respond to :create_authenticator, but doesn't"
|
221
|
-
end
|
232
|
+
Util.assert_responds_to(:create_authenticator, auth_provider) { ":auth_provider #{auth_provider.inspect} must respond to :create_authenticator, but doesn't" }
|
222
233
|
end
|
223
234
|
|
224
235
|
has_client_cert = options.has_key?(:client_cert)
|
@@ -236,13 +247,8 @@ module Cassandra
|
|
236
247
|
client_cert = ::File.expand_path(options[:client_cert])
|
237
248
|
private_key = ::File.expand_path(options[:private_key])
|
238
249
|
|
239
|
-
|
240
|
-
|
241
|
-
end
|
242
|
-
|
243
|
-
unless ::File.exists?(private_key)
|
244
|
-
raise ::ArgumentError, ":private_key #{private_key.inspect} doesn't exist"
|
245
|
-
end
|
250
|
+
Util.assert_file_exists(client_cert) { ":client_cert #{client_cert.inspect} doesn't exist" }
|
251
|
+
Util.assert_file_exists(private_key) { ":private_key #{private_key.inspect} doesn't exist" }
|
246
252
|
end
|
247
253
|
|
248
254
|
has_server_cert = options.has_key?(:server_cert)
|
@@ -250,9 +256,7 @@ module Cassandra
|
|
250
256
|
if has_server_cert
|
251
257
|
server_cert = ::File.expand_path(options[:server_cert])
|
252
258
|
|
253
|
-
|
254
|
-
raise ::ArgumentError, ":server_cert #{server_cert.inspect} doesn't exist"
|
255
|
-
end
|
259
|
+
Util.assert_file_exists(server_cert) { ":server_cert #{server_cert.inspect} doesn't exist" }
|
256
260
|
end
|
257
261
|
|
258
262
|
if has_client_cert || has_server_cert
|
@@ -279,9 +283,7 @@ module Cassandra
|
|
279
283
|
if options.has_key?(:ssl)
|
280
284
|
ssl = options[:ssl]
|
281
285
|
|
282
|
-
|
283
|
-
raise ::ArgumentError, ":ssl must be a boolean or an OpenSSL::SSL::SSLContext, #{ssl.inspect} given"
|
284
|
-
end
|
286
|
+
Util.assert_instance_of_one_of([::TrueClass, ::FalseClass, ::OpenSSL::SSL::SSLContext], ssl) { ":ssl must be a boolean or an OpenSSL::SSL::SSLContext, #{ssl.inspect} given" }
|
285
287
|
end
|
286
288
|
|
287
289
|
if options.has_key?(:compression)
|
@@ -303,26 +305,20 @@ module Cassandra
|
|
303
305
|
compressor = options[:compressor]
|
304
306
|
methods = [:algorithm, :compress?, :compress, :decompress]
|
305
307
|
|
306
|
-
|
307
|
-
raise ::ArgumentError, ":compressor #{compressor.inspect} must respond to #{methods.inspect}, but doesn't"
|
308
|
-
end
|
308
|
+
Util.assert_responds_to_all(methods, compressor) { ":compressor #{compressor.inspect} must respond to #{methods.inspect}, but doesn't" }
|
309
309
|
end
|
310
310
|
|
311
311
|
if options.has_key?(:logger)
|
312
312
|
logger = options[:logger]
|
313
313
|
methods = [:debug, :info, :warn, :error, :fatal]
|
314
314
|
|
315
|
-
|
316
|
-
raise ::ArgumentError, ":logger #{logger.inspect} must respond to #{methods.inspect}, but doesn't"
|
317
|
-
end
|
315
|
+
Util.assert_responds_to_all(methods, logger) { ":logger #{logger.inspect} must respond to #{methods.inspect}, but doesn't" }
|
318
316
|
end
|
319
317
|
|
320
318
|
if options.has_key?(:port)
|
321
319
|
port = options[:port] = Integer(options[:port])
|
322
320
|
|
323
|
-
|
324
|
-
raise ::ArgumentError, ":port must be a valid ip port, #{port.given}"
|
325
|
-
end
|
321
|
+
Util.assert_one_of(0..65536, port) { ":port must be a valid ip port, #{port} given" }
|
326
322
|
end
|
327
323
|
|
328
324
|
if options.has_key?(:datacenter)
|
@@ -330,34 +326,38 @@ module Cassandra
|
|
330
326
|
end
|
331
327
|
|
332
328
|
if options.has_key?(:connect_timeout)
|
333
|
-
timeout = options[:connect_timeout]
|
329
|
+
timeout = options[:connect_timeout]
|
334
330
|
|
335
|
-
|
336
|
-
|
331
|
+
unless timeout.nil?
|
332
|
+
Util.assert_instance_of(::Numeric, timeout) { ":connect_timeout must be a number of seconds, #{timeout} given" }
|
333
|
+
Util.assert(timeout > 0) { ":connect_timeout must be greater than 0, #{timeout} given" }
|
337
334
|
end
|
338
335
|
end
|
339
336
|
|
340
337
|
if options.has_key?(:timeout)
|
341
|
-
timeout = options[:timeout]
|
338
|
+
timeout = options[:timeout]
|
342
339
|
|
343
|
-
|
344
|
-
|
340
|
+
unless timeout.nil?
|
341
|
+
Util.assert_instance_of(::Numeric, timeout) { ":timeout must be a number of seconds, #{timeout} given" }
|
342
|
+
Util.assert(timeout > 0) { ":timeout must be greater than 0, #{timeout} given" }
|
345
343
|
end
|
346
344
|
end
|
347
345
|
|
348
346
|
if options.has_key?(:heartbeat_interval)
|
349
|
-
timeout = options[:heartbeat_interval]
|
347
|
+
timeout = options[:heartbeat_interval]
|
350
348
|
|
351
|
-
|
352
|
-
|
349
|
+
unless timeout.nil?
|
350
|
+
Util.assert_instance_of(::Numeric, timeout) { ":heartbeat_interval must be a number of seconds, #{timeout} given" }
|
351
|
+
Util.assert(timeout > 0) { ":heartbeat_interval must be greater than 0, #{timeout} given" }
|
353
352
|
end
|
354
353
|
end
|
355
354
|
|
356
355
|
if options.has_key?(:idle_timeout)
|
357
|
-
timeout = options[:idle_timeout]
|
356
|
+
timeout = options[:idle_timeout]
|
358
357
|
|
359
|
-
|
360
|
-
|
358
|
+
unless timeout.nil?
|
359
|
+
Util.assert_instance_of(::Numeric, timeout) { ":idle_timeout must be a number of seconds, #{timeout} given" }
|
360
|
+
Util.assert(timeout > 0) { ":idle_timeout must be greater than 0, #{timeout} given" }
|
361
361
|
end
|
362
362
|
end
|
363
363
|
|
@@ -365,42 +365,32 @@ module Cassandra
|
|
365
365
|
load_balancing_policy = options[:load_balancing_policy]
|
366
366
|
methods = [:host_up, :host_down, :host_found, :host_lost, :setup, :distance, :plan]
|
367
367
|
|
368
|
-
|
369
|
-
raise ::ArgumentError, ":load_balancing_policy #{load_balancing_policy.inspect} must respond to #{methods.inspect}, but doesn't"
|
370
|
-
end
|
368
|
+
Util.assert_responds_to_all(methods, load_balancing_policy) { ":load_balancing_policy #{load_balancing_policy.inspect} must respond to #{methods.inspect}, but doesn't" }
|
371
369
|
end
|
372
370
|
|
373
371
|
if options.has_key?(:reconnection_policy)
|
374
372
|
reconnection_policy = options[:reconnection_policy]
|
375
373
|
|
376
|
-
|
377
|
-
raise ::ArgumentError, ":reconnection_policy #{reconnection_policy.inspect} must respond to :schedule, but doesn't"
|
378
|
-
end
|
374
|
+
Util.assert_responds_to(:schedule, reconnection_policy) { ":reconnection_policy #{reconnection_policy.inspect} must respond to :schedule, but doesn't" }
|
379
375
|
end
|
380
376
|
|
381
377
|
if options.has_key?(:retry_policy)
|
382
378
|
retry_policy = options[:retry_policy]
|
383
379
|
methods = [:read_timeout, :write_timeout, :unavailable]
|
384
380
|
|
385
|
-
|
386
|
-
raise ::ArgumentError, ":retry_policy #{retry_policy.inspect} must respond to #{methods.inspect}, but doesn't"
|
387
|
-
end
|
381
|
+
Util.assert_responds_to_all(methods, retry_policy) { ":retry_policy #{retry_policy.inspect} must respond to #{methods.inspect}, but doesn't" }
|
388
382
|
end
|
389
383
|
|
390
384
|
if options.has_key?(:listeners)
|
391
385
|
listeners = options[:listeners]
|
392
386
|
|
393
|
-
|
394
|
-
raise ::ArgumentError, ":listeners must be an Enumerable, #{listeners.inspect} given"
|
395
|
-
end
|
387
|
+
Util.assert_instance_of(::Enumerable, listeners) { ":listeners must be an Enumerable, #{listeners.inspect} given" }
|
396
388
|
end
|
397
389
|
|
398
390
|
if options.has_key?(:consistency)
|
399
391
|
consistency = options[:consistency]
|
400
392
|
|
401
|
-
|
402
|
-
raise ::ArgumentError, ":consistency must be one of #{CONSISTENCIES.inspect}, #{consistency.inspect} given"
|
403
|
-
end
|
393
|
+
Util.assert_one_of(CONSISTENCIES, consistency) { ":consistency must be one of #{CONSISTENCIES.inspect}, #{consistency.inspect} given" }
|
404
394
|
end
|
405
395
|
|
406
396
|
if options.has_key?(:trace)
|
@@ -408,10 +398,11 @@ module Cassandra
|
|
408
398
|
end
|
409
399
|
|
410
400
|
if options.has_key?(:page_size)
|
411
|
-
page_size = options[:page_size]
|
401
|
+
page_size = options[:page_size]
|
412
402
|
|
413
|
-
|
414
|
-
|
403
|
+
unless page_size.nil?
|
404
|
+
page_size = options[:page_size] = Integer(page_size)
|
405
|
+
Util.assert(page_size > 0) { ":page_size must be a positive integer, #{page_size.inspect} given" }
|
415
406
|
end
|
416
407
|
end
|
417
408
|
|
@@ -419,9 +410,7 @@ module Cassandra
|
|
419
410
|
futures_factory = options[:futures_factory]
|
420
411
|
methods = [:error, :value, :promise, :all]
|
421
412
|
|
422
|
-
|
423
|
-
raise ::ArgumentError, ":futures_factory #{futures_factory.inspect} must respond to #{methods.inspect}, but doesn't"
|
424
|
-
end
|
413
|
+
Util.assert_responds_to_all(methods, futures_factory) { ":futures_factory #{futures_factory.inspect} must respond to #{methods.inspect}, but doesn't" }
|
425
414
|
end
|
426
415
|
|
427
416
|
if options.has_key?(:address_resolution)
|
@@ -429,6 +418,7 @@ module Cassandra
|
|
429
418
|
|
430
419
|
case address_resolution
|
431
420
|
when :none
|
421
|
+
# do nothing
|
432
422
|
when :ec2_multi_region
|
433
423
|
options[:address_resolution_policy] = AddressResolution::Policies::EC2MultiRegion.new
|
434
424
|
else
|
@@ -439,9 +429,7 @@ module Cassandra
|
|
439
429
|
if options.has_key?(:address_resolution_policy)
|
440
430
|
address_resolver = options[:address_resolution_policy]
|
441
431
|
|
442
|
-
|
443
|
-
raise ::ArgumentError, ":address_resolution_policy must respond to :resolve, #{address_resolver.inspect} but doesn't"
|
444
|
-
end
|
432
|
+
Util.assert_responds_to(:resolve, address_resolver) { ":address_resolution_policy must respond to :resolve, #{address_resolver.inspect} but doesn't" }
|
445
433
|
end
|
446
434
|
|
447
435
|
hosts = []
|
@@ -462,8 +450,20 @@ module Cassandra
|
|
462
450
|
if hosts.empty?
|
463
451
|
raise ::ArgumentError, ":hosts #{options[:hosts].inspect} could not be resolved to any ip address"
|
464
452
|
end
|
453
|
+
rescue => e
|
454
|
+
futures.error(e)
|
455
|
+
else
|
456
|
+
promise = futures.promise
|
457
|
+
|
458
|
+
Driver.new(options).connect(hosts).on_complete do |f|
|
459
|
+
if f.resolved?
|
460
|
+
promise.fulfill(f.value)
|
461
|
+
else
|
462
|
+
f.on_failure {|e| promise.break(e)}
|
463
|
+
end
|
464
|
+
end
|
465
465
|
|
466
|
-
|
466
|
+
promise.future
|
467
467
|
end
|
468
468
|
end
|
469
469
|
|
@@ -473,7 +473,7 @@ require 'cassandra/time_uuid'
|
|
473
473
|
require 'cassandra/compression'
|
474
474
|
require 'cassandra/protocol'
|
475
475
|
require 'cassandra/auth'
|
476
|
-
require 'cassandra/
|
476
|
+
require 'cassandra/null_logger'
|
477
477
|
|
478
478
|
require 'cassandra/future'
|
479
479
|
require 'cassandra/cluster'
|