cassandra-driver 1.0.0.rc.1-java → 1.1.0-java
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 +4 -4
- data/README.md +58 -18
- data/lib/cassandra.rb +132 -93
- data/lib/cassandra/auth.rb +3 -3
- data/lib/cassandra/cluster.rb +65 -39
- data/lib/cassandra/cluster/client.rb +67 -28
- data/lib/cassandra/{client/connection_manager.rb → cluster/connection_pool.rb} +9 -3
- data/lib/cassandra/cluster/connector.rb +101 -30
- data/lib/cassandra/cluster/control_connection.rb +160 -96
- data/lib/cassandra/{client/null_logger.rb → cluster/failed_connection.rb} +12 -14
- data/lib/cassandra/cluster/options.rb +26 -11
- data/lib/cassandra/cluster/schema.rb +22 -1
- data/lib/cassandra/column.rb +5 -0
- data/lib/cassandra/driver.rb +46 -12
- data/lib/cassandra/errors.rb +5 -5
- data/lib/cassandra/execution/options.rb +42 -8
- data/lib/cassandra/execution/trace.rb +4 -4
- data/lib/cassandra/executors.rb +111 -0
- data/lib/cassandra/future.rb +88 -64
- data/lib/cassandra/keyspace.rb +12 -0
- data/lib/cassandra/load_balancing.rb +10 -0
- data/lib/cassandra/load_balancing/policies/dc_aware_round_robin.rb +10 -5
- data/lib/cassandra/load_balancing/policies/round_robin.rb +7 -5
- data/lib/cassandra/load_balancing/policies/token_aware.rb +31 -10
- data/lib/cassandra/load_balancing/policies/white_list.rb +4 -7
- data/lib/cassandra/null_logger.rb +35 -0
- data/lib/cassandra/protocol/cql_protocol_handler.rb +8 -1
- data/lib/cassandra/protocol/requests/query_request.rb +1 -11
- data/lib/cassandra/result.rb +34 -9
- data/lib/cassandra/session.rb +6 -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 +40 -50
- 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,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ba36bd754db916c52e42130906733192c16ec6fa
|
4
|
+
data.tar.gz: dd30b1f020b3647d686e901638305b93c6286412
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e4e143ed5e11f1d2f88fefee54acd0ac3a92ffd2d8f650cf34b2c090041ee1f8e359c3b9c2b93dafd2e6ec8582a691d351e1c8371c4bc376e630273f3e1c0e0e
|
7
|
+
data.tar.gz: bca986745e23c0efc77e24cf2f816e94db79479079dfa2c115476f6d9c14b9c69ad17468f112ea6b65dc4f803f62da14048d25f16ec1eb4f1a073b8e4efb71c7
|
data/README.md
CHANGED
@@ -9,27 +9,35 @@ 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
|
|
19
|
-
* [
|
20
|
-
*
|
21
|
-
*
|
22
|
-
*
|
19
|
+
* [Asynchronous execution](http://datastax.github.io/ruby-driver/features/asynchronous_io/)
|
20
|
+
* 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/)
|
21
|
+
* Automatic peer discovery and cluster metadata with [support for change notifications](http://datastax.github.io/ruby-driver/features/state_listeners/)
|
22
|
+
* Various [load-balancing](http://datastax.github.io/ruby-driver/features/load_balancing/), [retry](http://datastax.github.io/ruby-driver/features/retry_policies/) and [reconnection](http://datastax.github.io/ruby-driver/features/reconnection/) policies with [ability to write your own](http://datastax.github.io/ruby-driver/features/load_balancing/implementing_a_policy/)
|
23
23
|
* [SSL encryption](http://datastax.github.io/ruby-driver/features/security/ssl_encryption/)
|
24
|
+
* [Flexible and robust error handling](http://datastax.github.io/ruby-driver/features/error_handling/)
|
25
|
+
* [Per-request execution information and tracing](http://datastax.github.io/ruby-driver/features/debugging/)
|
26
|
+
* [Configurable address resolution](http://datastax.github.io/ruby-driver/features/address_resolution/)
|
27
|
+
|
28
|
+
[Check out the slides from Ruby Driver Explained](https://speakerdeck.com/avalanche123/ruby-driver-explained) for a detailed overview of the Ruby Driver architecture.
|
24
29
|
|
25
30
|
## Compability
|
26
31
|
|
27
32
|
This driver works exclusively with the Cassandra Query Language v3 (CQL3) and Cassandra's native protocol. The current version works with:
|
28
33
|
|
29
|
-
* Cassandra versions 1.2 and 2.
|
30
|
-
*
|
34
|
+
* Apache Cassandra versions 1.2, 2.0 and partially 2.1
|
35
|
+
* DataStax Enterprise 3.1, 3.2, 4.0 and 4.5
|
36
|
+
* Ruby (MRI) 1.9.3, 2.0 and 2.1
|
31
37
|
* JRuby 1.7
|
32
|
-
* Rubinius 2.
|
38
|
+
* Rubinius 2.2
|
39
|
+
|
40
|
+
__Note__: Apache Cassandra 2.1 support is limited to the Cassandra 2.0 API, e.g. no user-defined types.
|
33
41
|
|
34
42
|
__Note__: JRuby 1.6 is not officially supported, although 1.6.8 should work.
|
35
43
|
|
@@ -56,7 +64,7 @@ end
|
|
56
64
|
future.join
|
57
65
|
```
|
58
66
|
|
59
|
-
The host you specify is just a seed node, the driver will automatically discover all peers in the cluster.
|
67
|
+
__Note__: The host you specify is just a seed node, the driver will automatically discover all peers in the cluster.
|
60
68
|
|
61
69
|
Read more:
|
62
70
|
|
@@ -69,29 +77,59 @@ Read more:
|
|
69
77
|
Install via rubygems
|
70
78
|
|
71
79
|
```bash
|
72
|
-
gem install cassandra-driver
|
80
|
+
gem install cassandra-driver
|
73
81
|
```
|
74
82
|
|
75
83
|
Install via Gemfile
|
76
84
|
|
77
85
|
```ruby
|
78
|
-
gem 'cassandra-driver', '~> 1.0.0
|
86
|
+
gem 'cassandra-driver', '~> 1.0.0'
|
79
87
|
```
|
80
88
|
|
81
|
-
|
89
|
+
__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)
|
82
90
|
|
83
91
|
|
84
92
|
## Upgrading from cql-rb
|
85
93
|
|
86
94
|
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
95
|
|
88
|
-
## What's new in v1.
|
96
|
+
## What's new in v1.1.0
|
89
97
|
|
90
98
|
Current release introduces the following new features:
|
91
99
|
|
92
|
-
*
|
93
|
-
*
|
94
|
-
*
|
100
|
+
* Ability to disable automatic schema synchronization
|
101
|
+
* Schema change event storm protection using a sliding delay
|
102
|
+
* [`Cassandra::LoadBalancing::Policy#teardown`](http://datastax.github.io/ruby-driver/api/load_balancing/policy/#teardown-instance_method) for cleaning up resources
|
103
|
+
* [`Cassandra::Cluster#refresh_schema`](http://datastax.github.io/ruby-driver/api/cluster/#refresh_schema-instance_method) for manually refreshing schema metadata
|
104
|
+
* Host list randomization to prevent hotspots between multiple clients
|
105
|
+
* Future listeners run in a dedicated threadpool to not block the reactor
|
106
|
+
|
107
|
+
## Code examples
|
108
|
+
|
109
|
+
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.
|
110
|
+
|
111
|
+
## Running tests
|
112
|
+
|
113
|
+
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).
|
114
|
+
|
115
|
+
* Check out the driver codebase and install test dependencies:
|
116
|
+
|
117
|
+
```bash
|
118
|
+
git clone https://github.com/datastax/ruby-driver.git
|
119
|
+
cd ruby-driver
|
120
|
+
bundle install --without docs
|
121
|
+
```
|
122
|
+
|
123
|
+
* [Install ccm](http://www.datastax.com/dev/blog/ccm-a-development-tool-for-creating-local-cassandra-clusters)
|
124
|
+
|
125
|
+
* Run tests:
|
126
|
+
|
127
|
+
```bash
|
128
|
+
bundle exec cucumber # runs end-to-end tests (or bundle exec rake cucumber)
|
129
|
+
bundle exec rspec # runs unit tests (or bundle exec rake rspec)
|
130
|
+
bundle exec rake integration # run integration tests
|
131
|
+
bundle exec rake test # run both as well as integration tests
|
132
|
+
```
|
95
133
|
|
96
134
|
## Changelog & versioning
|
97
135
|
|
@@ -105,7 +143,9 @@ Prereleases will be stable, in the sense that they will have finished and proper
|
|
105
143
|
|
106
144
|
* 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
145
|
* Because the driver reactor is using `IO.select`, the maximum number of tcp connections allowed is 1024.
|
146
|
+
* Because the driver uses `IO#write_nonblock`, Windows is not supported.
|
108
147
|
|
148
|
+
Please [refer to the usage documentation for more information on common pitfalls](http://datastax.github.io/ruby-driver/features/)
|
109
149
|
|
110
150
|
## Credits
|
111
151
|
|
data/lib/cassandra.rb
CHANGED
@@ -25,7 +25,6 @@ require 'ipaddr'
|
|
25
25
|
require 'set'
|
26
26
|
require 'bigdecimal'
|
27
27
|
require 'forwardable'
|
28
|
-
require 'timeout'
|
29
28
|
require 'digest'
|
30
29
|
require 'stringio'
|
31
30
|
require 'resolv'
|
@@ -51,7 +50,7 @@ module Cassandra
|
|
51
50
|
# @see https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v1.spec#L591-L603 Description of possible types of writes in Apache Cassandra native protocol spec v1
|
52
51
|
WRITE_TYPES = [:simple, :batch, :unlogged_batch, :counter, :batch_log].freeze
|
53
52
|
|
54
|
-
# Creates a {Cassandra::Cluster
|
53
|
+
# Creates a {Cassandra::Cluster Cluster instance}.
|
55
54
|
#
|
56
55
|
# @option options [Array<String, IPAddr>] :hosts (['127.0.0.1']) a list of
|
57
56
|
# initial addresses. Note that the entire list of cluster members will be
|
@@ -65,22 +64,27 @@ module Cassandra
|
|
65
64
|
# can skip this option if you specify only hosts from the local datacenter
|
66
65
|
# in `:hosts` option.
|
67
66
|
#
|
67
|
+
# @option options [Boolean] :shuffle_replicas (true) whether replicas list
|
68
|
+
# found by the default Token-Aware Load Balancing Policy should be
|
69
|
+
# shuffled. See {Cassandra::LoadBalancing::Policies::TokenAware#initialize Token-Aware Load Balancing Policy}.
|
70
|
+
#
|
68
71
|
# @option options [Numeric] :connect_timeout (10) connection timeout in
|
69
|
-
# seconds.
|
72
|
+
# seconds. Setting value to `nil` will reset it to 5 seconds.
|
70
73
|
#
|
71
74
|
# @option options [Numeric] :timeout (10) request execution timeout in
|
72
|
-
# seconds.
|
75
|
+
# seconds. Setting value to `nil` will remove request timeout.
|
73
76
|
#
|
74
77
|
# @option options [Numeric] :heartbeat_interval (30) how often should a
|
75
78
|
# heartbeat be sent to determine if a connection is alive. Several things to
|
76
79
|
# note about this option. Only one heartbeat request will ever be
|
77
80
|
# outstanding on a given connection. Each heatbeat will be sent in at least
|
78
81
|
# `:heartbeat_interval` seconds after the last request has been sent on a
|
79
|
-
# given connection.
|
82
|
+
# given connection. Setting value to `nil` will remove connection timeout.
|
80
83
|
#
|
81
84
|
# @option options [Numeric] :idle_timeout (60) period of inactivity after
|
82
85
|
# which a connection is considered dead. Note that this value should be at
|
83
|
-
# least a few times larger than `:heartbeat_interval`.
|
86
|
+
# least a few times larger than `:heartbeat_interval`. Setting value to
|
87
|
+
# `nil` will remove automatic connection termination.
|
84
88
|
#
|
85
89
|
# @option options [String] :username (none) username to use for
|
86
90
|
# authentication to cassandra. Note that you must also specify `:password`.
|
@@ -118,12 +122,33 @@ module Cassandra
|
|
118
122
|
# address resolver to use. Must be one of `:none` or
|
119
123
|
# `:ec2_multi_region`.
|
120
124
|
#
|
125
|
+
# @option options [Boolean] :synchronize_schema (true) whether the driver
|
126
|
+
# should automatically keep schema metadata synchronized. When enabled, the
|
127
|
+
# driver updates schema metadata after receiving schema change
|
128
|
+
# notifications from Cassandra. Setting this setting to `false` disables
|
129
|
+
# automatic schema updates. Schema metadata is used by the driver to
|
130
|
+
# determine cluster partitioners as well as to find partition keys and
|
131
|
+
# replicas of prepared statements, this information makes token aware load
|
132
|
+
# balancing possible. One can still {Cassandra::Cluster#refresh_schema refresh schema manually}.
|
133
|
+
#
|
134
|
+
# @option options [Numeric] :schema_refresh_delay (1) the driver will wait
|
135
|
+
# for `:schema_refresh_delay` before fetching metadata after receiving a
|
136
|
+
# schema change event. This timer is restarted every time a new schema
|
137
|
+
# change event is received. Finally, when the timer expires or a maximum
|
138
|
+
# wait time of `:schema_refresh_timeout` has been reached, a schema refresh
|
139
|
+
# attempt will be made and the timeout is reset.
|
140
|
+
#
|
141
|
+
# @option options [Numeric] :schema_refresh_timeout (10) the maximum delay
|
142
|
+
# before automatically refreshing schema. Such delay can occur whenever
|
143
|
+
# multiple schema change events are continuously arriving within
|
144
|
+
# `:schema_refresh_delay` interval.
|
145
|
+
#
|
121
146
|
# @option options [Cassandra::Reconnection::Policy] :reconnection_policy
|
122
|
-
# default: {Cassandra::Reconnection::Policies::Exponential}.
|
123
|
-
# default policy is configured with `(0.5, 30, 2)`.
|
147
|
+
# default: {Cassandra::Reconnection::Policies::Exponential Exponential}.
|
148
|
+
# Note that the default policy is configured with `(0.5, 30, 2)`.
|
124
149
|
#
|
125
150
|
# @option options [Cassandra::Retry::Policy] :retry_policy default:
|
126
|
-
# {Cassandra::Retry::Policies::Default}.
|
151
|
+
# {Cassandra::Retry::Policies::Default Default Retry Policy}.
|
127
152
|
#
|
128
153
|
# @option options [Logger] :logger (none) logger. a {Logger} instance from the
|
129
154
|
# standard library or any object responding to standard log methods
|
@@ -139,28 +164,28 @@ module Cassandra
|
|
139
164
|
# @option options [Boolean] :trace (false) whether or not to trace all
|
140
165
|
# requests by default.
|
141
166
|
#
|
142
|
-
# @option options [Integer] :page_size (
|
143
|
-
# queries.
|
167
|
+
# @option options [Integer] :page_size (10000) default page size for all
|
168
|
+
# select queries. Set this value to `nil` to disable paging.
|
144
169
|
#
|
145
170
|
# @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
171
|
#
|
147
|
-
# @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.
|
172
|
+
# @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 Password Provider} will be used automatically.
|
148
173
|
#
|
149
|
-
# @option options [Cassandra::Compressor] :compressor (none) a
|
150
|
-
# compressor. Note that if you have specified `:compression`, an
|
174
|
+
# @option options [Cassandra::Compression::Compressor] :compressor (none) a
|
175
|
+
# custom compressor. Note that if you have specified `:compression`, an
|
151
176
|
# appropriate compressor will be provided automatically.
|
152
177
|
#
|
153
178
|
# @option options [Cassandra::AddressResolution::Policy]
|
154
179
|
# :address_resolution_policy default:
|
155
|
-
# {Cassandra::AddressResolution::Policies::None} a custom address resolution
|
180
|
+
# {Cassandra::AddressResolution::Policies::None No Resolution Policy} a custom address resolution
|
156
181
|
# policy. Note that if you have specified `:address_resolution`, an
|
157
182
|
# appropriate address resolution policy will be provided automatically.
|
158
183
|
#
|
159
184
|
# @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.
|
185
|
+
# default: {Cassandra::Future} a futures factory to assist with integration
|
186
|
+
# into existing futures library. Note that promises returned by this object
|
187
|
+
# must conform to {Cassandra::Promise} api, which is not yet public. Things
|
188
|
+
# may change, use at your own risk.
|
164
189
|
#
|
165
190
|
# @example Connecting to localhost
|
166
191
|
# cluster = Cassandra.cluster
|
@@ -174,13 +199,25 @@ module Cassandra
|
|
174
199
|
#
|
175
200
|
# @return [Cassandra::Cluster] a cluster instance
|
176
201
|
def self.cluster(options = {})
|
202
|
+
cluster_async(options).get
|
203
|
+
end
|
204
|
+
|
205
|
+
# Creates a {Cassandra::Cluster Cluster instance}.
|
206
|
+
#
|
207
|
+
# @see Cassandra.cluster
|
208
|
+
#
|
209
|
+
# @return [Cassandra::Future<Cassandra::Cluster>] a future resolving to the
|
210
|
+
# cluster instance.
|
211
|
+
def self.cluster_async(options = {})
|
177
212
|
options = options.select do |key, value|
|
178
213
|
[ :credentials, :auth_provider, :compression, :hosts, :logger, :port,
|
179
214
|
:load_balancing_policy, :reconnection_policy, :retry_policy, :listeners,
|
180
215
|
:consistency, :trace, :page_size, :compressor, :username, :password,
|
181
216
|
:ssl, :server_cert, :client_cert, :private_key, :passphrase,
|
182
217
|
:connect_timeout, :futures_factory, :datacenter, :address_resolution,
|
183
|
-
:address_resolution_policy, :idle_timeout, :heartbeat_interval, :timeout
|
218
|
+
:address_resolution_policy, :idle_timeout, :heartbeat_interval, :timeout,
|
219
|
+
:synchronize_schema, :schema_refresh_delay, :schema_refresh_timeout,
|
220
|
+
:shuffle_replicas
|
184
221
|
].include?(key)
|
185
222
|
end
|
186
223
|
|
@@ -195,11 +232,13 @@ module Cassandra
|
|
195
232
|
raise ::ArgumentError, "both :username and :password options must be specified, but only :password given"
|
196
233
|
end
|
197
234
|
|
198
|
-
username =
|
199
|
-
password =
|
235
|
+
username = options.delete(:username)
|
236
|
+
password = options.delete(:password)
|
200
237
|
|
201
|
-
|
202
|
-
|
238
|
+
Util.assert_instance_of(::String, username) { ":username must be a String, #{username.inspect} given" }
|
239
|
+
Util.assert_instance_of(::String, password) { ":password must be a String, #{password.inspect} given" }
|
240
|
+
Util.assert_not_empty(username) { ":username cannot be empty" }
|
241
|
+
Util.assert_not_empty(password) { ":password cannot be empty" }
|
203
242
|
|
204
243
|
options[:credentials] = {:username => username, :password => password}
|
205
244
|
options[:auth_provider] = Auth::Providers::Password.new(username, password)
|
@@ -208,17 +247,13 @@ module Cassandra
|
|
208
247
|
if options.has_key?(:credentials)
|
209
248
|
credentials = options[:credentials]
|
210
249
|
|
211
|
-
|
212
|
-
raise ::ArgumentError, ":credentials must be a hash, #{credentials.inspect} given"
|
213
|
-
end
|
250
|
+
Util.assert_instance_of(::Hash, credentials) { ":credentials must be a hash, #{credentials.inspect} given" }
|
214
251
|
end
|
215
252
|
|
216
253
|
if options.has_key?(:auth_provider)
|
217
254
|
auth_provider = options[:auth_provider]
|
218
255
|
|
219
|
-
|
220
|
-
raise ::ArgumentError, ":auth_provider #{auth_provider.inspect} must respond to :create_authenticator, but doesn't"
|
221
|
-
end
|
256
|
+
Util.assert_responds_to(:create_authenticator, auth_provider) { ":auth_provider #{auth_provider.inspect} must respond to :create_authenticator, but doesn't" }
|
222
257
|
end
|
223
258
|
|
224
259
|
has_client_cert = options.has_key?(:client_cert)
|
@@ -236,13 +271,8 @@ module Cassandra
|
|
236
271
|
client_cert = ::File.expand_path(options[:client_cert])
|
237
272
|
private_key = ::File.expand_path(options[:private_key])
|
238
273
|
|
239
|
-
|
240
|
-
|
241
|
-
end
|
242
|
-
|
243
|
-
unless ::File.exists?(private_key)
|
244
|
-
raise ::ArgumentError, ":private_key #{private_key.inspect} doesn't exist"
|
245
|
-
end
|
274
|
+
Util.assert_file_exists(client_cert) { ":client_cert #{client_cert.inspect} doesn't exist" }
|
275
|
+
Util.assert_file_exists(private_key) { ":private_key #{private_key.inspect} doesn't exist" }
|
246
276
|
end
|
247
277
|
|
248
278
|
has_server_cert = options.has_key?(:server_cert)
|
@@ -250,9 +280,7 @@ module Cassandra
|
|
250
280
|
if has_server_cert
|
251
281
|
server_cert = ::File.expand_path(options[:server_cert])
|
252
282
|
|
253
|
-
|
254
|
-
raise ::ArgumentError, ":server_cert #{server_cert.inspect} doesn't exist"
|
255
|
-
end
|
283
|
+
Util.assert_file_exists(server_cert) { ":server_cert #{server_cert.inspect} doesn't exist" }
|
256
284
|
end
|
257
285
|
|
258
286
|
if has_client_cert || has_server_cert
|
@@ -279,9 +307,7 @@ module Cassandra
|
|
279
307
|
if options.has_key?(:ssl)
|
280
308
|
ssl = options[:ssl]
|
281
309
|
|
282
|
-
|
283
|
-
raise ::ArgumentError, ":ssl must be a boolean or an OpenSSL::SSL::SSLContext, #{ssl.inspect} given"
|
284
|
-
end
|
310
|
+
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
311
|
end
|
286
312
|
|
287
313
|
if options.has_key?(:compression)
|
@@ -303,26 +329,20 @@ module Cassandra
|
|
303
329
|
compressor = options[:compressor]
|
304
330
|
methods = [:algorithm, :compress?, :compress, :decompress]
|
305
331
|
|
306
|
-
|
307
|
-
raise ::ArgumentError, ":compressor #{compressor.inspect} must respond to #{methods.inspect}, but doesn't"
|
308
|
-
end
|
332
|
+
Util.assert_responds_to_all(methods, compressor) { ":compressor #{compressor.inspect} must respond to #{methods.inspect}, but doesn't" }
|
309
333
|
end
|
310
334
|
|
311
335
|
if options.has_key?(:logger)
|
312
336
|
logger = options[:logger]
|
313
337
|
methods = [:debug, :info, :warn, :error, :fatal]
|
314
338
|
|
315
|
-
|
316
|
-
raise ::ArgumentError, ":logger #{logger.inspect} must respond to #{methods.inspect}, but doesn't"
|
317
|
-
end
|
339
|
+
Util.assert_responds_to_all(methods, logger) { ":logger #{logger.inspect} must respond to #{methods.inspect}, but doesn't" }
|
318
340
|
end
|
319
341
|
|
320
342
|
if options.has_key?(:port)
|
321
343
|
port = options[:port] = Integer(options[:port])
|
322
344
|
|
323
|
-
|
324
|
-
raise ::ArgumentError, ":port must be a valid ip port, #{port.given}"
|
325
|
-
end
|
345
|
+
Util.assert_one_of(0..65536, port) { ":port must be a valid ip port, #{port} given" }
|
326
346
|
end
|
327
347
|
|
328
348
|
if options.has_key?(:datacenter)
|
@@ -330,88 +350,99 @@ module Cassandra
|
|
330
350
|
end
|
331
351
|
|
332
352
|
if options.has_key?(:connect_timeout)
|
333
|
-
timeout = options[:connect_timeout]
|
353
|
+
timeout = options[:connect_timeout]
|
334
354
|
|
335
|
-
|
336
|
-
|
355
|
+
unless timeout.nil?
|
356
|
+
Util.assert_instance_of(::Numeric, timeout) { ":connect_timeout must be a number of seconds, #{timeout} given" }
|
357
|
+
Util.assert(timeout > 0) { ":connect_timeout must be greater than 0, #{timeout} given" }
|
337
358
|
end
|
338
359
|
end
|
339
360
|
|
340
361
|
if options.has_key?(:timeout)
|
341
|
-
timeout = options[:timeout]
|
362
|
+
timeout = options[:timeout]
|
342
363
|
|
343
|
-
|
344
|
-
|
364
|
+
unless timeout.nil?
|
365
|
+
Util.assert_instance_of(::Numeric, timeout) { ":timeout must be a number of seconds, #{timeout} given" }
|
366
|
+
Util.assert(timeout > 0) { ":timeout must be greater than 0, #{timeout} given" }
|
345
367
|
end
|
346
368
|
end
|
347
369
|
|
348
370
|
if options.has_key?(:heartbeat_interval)
|
349
|
-
timeout = options[:heartbeat_interval]
|
371
|
+
timeout = options[:heartbeat_interval]
|
350
372
|
|
351
|
-
|
352
|
-
|
373
|
+
unless timeout.nil?
|
374
|
+
Util.assert_instance_of(::Numeric, timeout) { ":heartbeat_interval must be a number of seconds, #{timeout} given" }
|
375
|
+
Util.assert(timeout > 0) { ":heartbeat_interval must be greater than 0, #{timeout} given" }
|
353
376
|
end
|
354
377
|
end
|
355
378
|
|
356
379
|
if options.has_key?(:idle_timeout)
|
357
|
-
timeout = options[:idle_timeout]
|
380
|
+
timeout = options[:idle_timeout]
|
358
381
|
|
359
|
-
|
360
|
-
|
382
|
+
unless timeout.nil?
|
383
|
+
Util.assert_instance_of(::Numeric, timeout) { ":idle_timeout must be a number of seconds, #{timeout} given" }
|
384
|
+
Util.assert(timeout > 0) { ":idle_timeout must be greater than 0, #{timeout} given" }
|
361
385
|
end
|
362
386
|
end
|
363
387
|
|
388
|
+
if options.has_key?(:schema_refresh_delay)
|
389
|
+
timeout = options[:schema_refresh_delay]
|
390
|
+
|
391
|
+
Util.assert_instance_of(::Numeric, timeout) { ":schema_refresh_delay must be a number of seconds, #{timeout} given" }
|
392
|
+
Util.assert(timeout > 0) { ":schema_refresh_delay must be greater than 0, #{timeout} given" }
|
393
|
+
end
|
394
|
+
|
395
|
+
if options.has_key?(:schema_refresh_timeout)
|
396
|
+
timeout = options[:schema_refresh_timeout]
|
397
|
+
|
398
|
+
Util.assert_instance_of(::Numeric, timeout) { ":schema_refresh_timeout must be a number of seconds, #{timeout} given" }
|
399
|
+
Util.assert(timeout > 0) { ":schema_refresh_timeout must be greater than 0, #{timeout} given" }
|
400
|
+
end
|
401
|
+
|
364
402
|
if options.has_key?(:load_balancing_policy)
|
365
403
|
load_balancing_policy = options[:load_balancing_policy]
|
366
|
-
methods = [:host_up, :host_down, :host_found, :host_lost, :setup, :distance, :plan]
|
404
|
+
methods = [:host_up, :host_down, :host_found, :host_lost, :setup, :teardown, :distance, :plan]
|
367
405
|
|
368
|
-
|
369
|
-
raise ::ArgumentError, ":load_balancing_policy #{load_balancing_policy.inspect} must respond to #{methods.inspect}, but doesn't"
|
370
|
-
end
|
406
|
+
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
407
|
end
|
372
408
|
|
373
409
|
if options.has_key?(:reconnection_policy)
|
374
410
|
reconnection_policy = options[:reconnection_policy]
|
375
411
|
|
376
|
-
|
377
|
-
raise ::ArgumentError, ":reconnection_policy #{reconnection_policy.inspect} must respond to :schedule, but doesn't"
|
378
|
-
end
|
412
|
+
Util.assert_responds_to(:schedule, reconnection_policy) { ":reconnection_policy #{reconnection_policy.inspect} must respond to :schedule, but doesn't" }
|
379
413
|
end
|
380
414
|
|
381
415
|
if options.has_key?(:retry_policy)
|
382
416
|
retry_policy = options[:retry_policy]
|
383
417
|
methods = [:read_timeout, :write_timeout, :unavailable]
|
384
418
|
|
385
|
-
|
386
|
-
raise ::ArgumentError, ":retry_policy #{retry_policy.inspect} must respond to #{methods.inspect}, but doesn't"
|
387
|
-
end
|
419
|
+
Util.assert_responds_to_all(methods, retry_policy) { ":retry_policy #{retry_policy.inspect} must respond to #{methods.inspect}, but doesn't" }
|
388
420
|
end
|
389
421
|
|
390
422
|
if options.has_key?(:listeners)
|
391
|
-
listeners = options[:listeners]
|
392
|
-
|
393
|
-
unless listeners.respond_to?(:each)
|
394
|
-
raise ::ArgumentError, ":listeners must be an Enumerable, #{listeners.inspect} given"
|
395
|
-
end
|
423
|
+
options[:listeners] = Array(options[:listeners])
|
396
424
|
end
|
397
425
|
|
398
426
|
if options.has_key?(:consistency)
|
399
427
|
consistency = options[:consistency]
|
400
428
|
|
401
|
-
|
402
|
-
raise ::ArgumentError, ":consistency must be one of #{CONSISTENCIES.inspect}, #{consistency.inspect} given"
|
403
|
-
end
|
429
|
+
Util.assert_one_of(CONSISTENCIES, consistency) { ":consistency must be one of #{CONSISTENCIES.inspect}, #{consistency.inspect} given" }
|
404
430
|
end
|
405
431
|
|
406
432
|
if options.has_key?(:trace)
|
407
433
|
options[:trace] = !!options[:trace]
|
408
434
|
end
|
409
435
|
|
436
|
+
if options.has_key?(:shuffle_replicas)
|
437
|
+
options[:shuffle_replicas] = !!options[:shuffle_replicas]
|
438
|
+
end
|
439
|
+
|
410
440
|
if options.has_key?(:page_size)
|
411
|
-
page_size = options[:page_size]
|
441
|
+
page_size = options[:page_size]
|
412
442
|
|
413
|
-
|
414
|
-
|
443
|
+
unless page_size.nil?
|
444
|
+
page_size = options[:page_size] = Integer(page_size)
|
445
|
+
Util.assert(page_size > 0) { ":page_size must be a positive integer, #{page_size.inspect} given" }
|
415
446
|
end
|
416
447
|
end
|
417
448
|
|
@@ -419,9 +450,7 @@ module Cassandra
|
|
419
450
|
futures_factory = options[:futures_factory]
|
420
451
|
methods = [:error, :value, :promise, :all]
|
421
452
|
|
422
|
-
|
423
|
-
raise ::ArgumentError, ":futures_factory #{futures_factory.inspect} must respond to #{methods.inspect}, but doesn't"
|
424
|
-
end
|
453
|
+
Util.assert_responds_to_all(methods, futures_factory) { ":futures_factory #{futures_factory.inspect} must respond to #{methods.inspect}, but doesn't" }
|
425
454
|
end
|
426
455
|
|
427
456
|
if options.has_key?(:address_resolution)
|
@@ -429,6 +458,7 @@ module Cassandra
|
|
429
458
|
|
430
459
|
case address_resolution
|
431
460
|
when :none
|
461
|
+
# do nothing
|
432
462
|
when :ec2_multi_region
|
433
463
|
options[:address_resolution_policy] = AddressResolution::Policies::EC2MultiRegion.new
|
434
464
|
else
|
@@ -439,9 +469,11 @@ module Cassandra
|
|
439
469
|
if options.has_key?(:address_resolution_policy)
|
440
470
|
address_resolver = options[:address_resolution_policy]
|
441
471
|
|
442
|
-
|
443
|
-
|
444
|
-
|
472
|
+
Util.assert_responds_to(:resolve, address_resolver) { ":address_resolution_policy must respond to :resolve, #{address_resolver.inspect} but doesn't" }
|
473
|
+
end
|
474
|
+
|
475
|
+
if options.has_key?(:synchronize_schema)
|
476
|
+
options[:synchronize_schema] = !!options[:synchronize_schema]
|
445
477
|
end
|
446
478
|
|
447
479
|
hosts = []
|
@@ -463,7 +495,13 @@ module Cassandra
|
|
463
495
|
raise ::ArgumentError, ":hosts #{options[:hosts].inspect} could not be resolved to any ip address"
|
464
496
|
end
|
465
497
|
|
466
|
-
|
498
|
+
hosts.shuffle!
|
499
|
+
rescue => e
|
500
|
+
futures = options.fetch(:futures_factory) { Driver.new.futures_factory }
|
501
|
+
futures.error(e)
|
502
|
+
else
|
503
|
+
driver = Driver.new(options)
|
504
|
+
driver.connect(hosts)
|
467
505
|
end
|
468
506
|
end
|
469
507
|
|
@@ -473,8 +511,9 @@ require 'cassandra/time_uuid'
|
|
473
511
|
require 'cassandra/compression'
|
474
512
|
require 'cassandra/protocol'
|
475
513
|
require 'cassandra/auth'
|
476
|
-
require 'cassandra/
|
514
|
+
require 'cassandra/null_logger'
|
477
515
|
|
516
|
+
require 'cassandra/executors'
|
478
517
|
require 'cassandra/future'
|
479
518
|
require 'cassandra/cluster'
|
480
519
|
require 'cassandra/driver'
|