cassandra-driver 3.0.0.rc.1 → 3.0.0.rc.2
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 +6 -1
- data/lib/cassandra.rb +74 -55
- data/lib/cassandra/attr_boolean.rb +33 -0
- data/lib/cassandra/auth.rb +2 -1
- data/lib/cassandra/auth/providers/password.rb +4 -16
- data/lib/cassandra/cluster/connector.rb +14 -4
- data/lib/cassandra/cluster/control_connection.rb +59 -67
- data/lib/cassandra/cluster/metadata.rb +1 -3
- data/lib/cassandra/cluster/options.rb +9 -10
- data/lib/cassandra/cluster/registry.rb +16 -5
- data/lib/cassandra/cluster/schema.rb +45 -1
- data/lib/cassandra/cluster/schema/fetchers.rb +475 -272
- data/lib/cassandra/cluster/schema/fqcn_type_parser.rb +2 -6
- data/lib/cassandra/cluster/schema/partitioners/murmur3.rb +5 -7
- data/lib/cassandra/column.rb +1 -20
- data/lib/cassandra/column_container.rb +322 -0
- data/lib/cassandra/compression/compressors/lz4.rb +3 -5
- data/lib/cassandra/driver.rb +1 -1
- data/lib/cassandra/errors.rb +38 -22
- data/lib/cassandra/execution/options.rb +4 -2
- data/lib/cassandra/future.rb +3 -9
- data/lib/cassandra/host.rb +16 -2
- data/lib/cassandra/index.rb +104 -0
- data/lib/cassandra/keyspace.rb +88 -9
- data/lib/cassandra/load_balancing/policies/dc_aware_round_robin.rb +6 -10
- data/lib/cassandra/materialized_view.rb +90 -0
- data/lib/cassandra/protocol/coder.rb +3 -3
- data/lib/cassandra/protocol/cql_byte_buffer.rb +12 -11
- data/lib/cassandra/protocol/cql_protocol_handler.rb +12 -8
- data/lib/cassandra/protocol/request.rb +4 -5
- data/lib/cassandra/protocol/requests/execute_request.rb +3 -5
- data/lib/cassandra/protocol/requests/query_request.rb +1 -1
- data/lib/cassandra/protocol/requests/startup_request.rb +6 -8
- data/lib/cassandra/protocol/response.rb +1 -2
- data/lib/cassandra/protocol/responses/auth_challenge_response.rb +3 -4
- data/lib/cassandra/protocol/responses/auth_success_response.rb +3 -4
- data/lib/cassandra/protocol/responses/authenticate_response.rb +3 -4
- data/lib/cassandra/protocol/responses/error_response.rb +3 -4
- data/lib/cassandra/protocol/responses/event_response.rb +2 -3
- data/lib/cassandra/protocol/responses/prepared_result_response.rb +3 -4
- data/lib/cassandra/protocol/responses/ready_response.rb +3 -4
- data/lib/cassandra/protocol/responses/result_response.rb +7 -8
- data/lib/cassandra/protocol/responses/rows_result_response.rb +3 -4
- data/lib/cassandra/protocol/responses/schema_change_event_response.rb +3 -4
- data/lib/cassandra/protocol/responses/schema_change_result_response.rb +3 -4
- data/lib/cassandra/protocol/responses/set_keyspace_result_response.rb +3 -4
- data/lib/cassandra/protocol/responses/status_change_event_response.rb +3 -4
- data/lib/cassandra/protocol/responses/supported_response.rb +3 -4
- data/lib/cassandra/protocol/responses/topology_change_event_response.rb +3 -4
- data/lib/cassandra/protocol/responses/void_result_response.rb +3 -4
- data/lib/cassandra/protocol/v1.rb +1 -5
- data/lib/cassandra/protocol/v3.rb +1 -3
- data/lib/cassandra/result.rb +2 -1
- data/lib/cassandra/retry/policies/downgrading_consistency.rb +1 -3
- data/lib/cassandra/statements/prepared.rb +3 -3
- data/lib/cassandra/table.rb +39 -220
- data/lib/cassandra/time_uuid.rb +5 -7
- data/lib/cassandra/tuple.rb +4 -12
- data/lib/cassandra/types.rb +92 -65
- data/lib/cassandra/udt.rb +34 -14
- data/lib/cassandra/uuid.rb +10 -18
- data/lib/cassandra/version.rb +1 -1
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZTBiZDQ4YTM2MDliN2U0N2VlNmJjY2RiYjQyOWVlOWI4MzlhNjNkZg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
OGY1MDNjN2Y5ZmFjYmY2YWY0ZWI0ZGNjZjViMTA1ZDdkYzQyOTg0Yg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MTIzOTk1Nzk0NDI2NWNkZWNiZmUyMmIzZjk4YjQ2YmRjZDkwODc4YjUxY2Fj
|
10
|
+
N2FmYjRlOGZiMjBlNTAzY2RmOGM4OGNlZmZkZWVjN2RjNDU1ZjY4MjYxODE3
|
11
|
+
YWU1MTZiNWMyMjViOTVhODExODlkNmQwMzc1ODZlMjkwYWU0NDQ=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZDI1ZDVmMWQyNzJiMGRiYzc5NTgxYjE4ZGEwNjVmZWM0Nzc0Yzk4MGJjODcx
|
14
|
+
YjEzYjNlNTZhOTU1YWY2M2JlZGUxZDA1YWU3NjRlMGE4ZmM4ODUyMTgyNmVj
|
15
|
+
NjU3NWUzYzFiMDNmOGJlZDg1ODJiYzJkMDQ3OGZhNjU3MWZlMTY=
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Datastax Ruby Driver for Apache Cassandra
|
2
2
|
|
3
|
-
*If you're reading this on GitHub, please note that this is the readme for the development version and that some features described here might not yet have been released. You can [find the documentation for latest version through ruby driver docs](http://datastax.github.io/ruby-driver/) or via the release tags, [e.g.
|
3
|
+
*If you're reading this on GitHub, please note that this is the readme for the development version and that some features described here might not yet have been released. You can [find the documentation for latest version through ruby driver docs](http://datastax.github.io/ruby-driver/) or via the release tags, [e.g. v3.0.0-rc.2](https://github.com/datastax/ruby-driver/tree/v3.0.0-rc.2).*
|
4
4
|
|
5
5
|
[](https://travis-ci.org/datastax/ruby-driver)
|
6
6
|
|
@@ -107,6 +107,8 @@ Some of the new features added to the driver have unfortunately led to changes i
|
|
107
107
|
* Expose server warnings on server exceptions and Cassandra::Execution::Info instances.
|
108
108
|
* Add connections_per_local_node, connections_per_remote_node, requests_per_connection cluster configuration options to tune parallel query execution and resource usage.
|
109
109
|
* Add Cassandra::Logger class to make it easy for users to enable debug logging in the client.
|
110
|
+
* Add protocol_version configuration option to allow the user to force the protocol version to use for communication with nodes.
|
111
|
+
* Add support for materialized views and indexes in the schema metadata.
|
110
112
|
|
111
113
|
### Breaking Changes:
|
112
114
|
|
@@ -133,6 +135,7 @@ batch.add(query, arguments: {p1: 'val1'})
|
|
133
135
|
* [[RUBY-143](https://datastax-oss.atlassian.net/browse/RUBY-143)] Retry querying system table for metadata of new hosts when prior attempts fail, ultimately enabling use of new hosts.
|
134
136
|
* [[RUBY-150](https://datastax-oss.atlassian.net/browse/RUBY-150)] Fixed a protocol decoding error that occurred when multiple messages are available in a stream.
|
135
137
|
* [[RUBY-151](https://datastax-oss.atlassian.net/browse/RUBY-151)] Decode incomplete UDTs properly.
|
138
|
+
* [[RUBY-161](https://datastax-oss.atlassian.net/browse/RUBY-161)] Protocol version negotiation in mixed version clusters should not fall back to v1 unless it is truly warranted.
|
136
139
|
|
137
140
|
## Feedback Requested
|
138
141
|
|
@@ -191,6 +194,8 @@ the release.
|
|
191
194
|
|
192
195
|
## Known bugs & limitations
|
193
196
|
|
197
|
+
* Specifying a `protocol_version` option of 1 or 2 in cluster options will fail with a
|
198
|
+
`NoHostsAvailable` error rather than a `ProtocolError` against Cassandra node versions 3.0-3.4.
|
194
199
|
* JRuby 1.6 is not officially supported, although 1.6.8 should work.
|
195
200
|
* Because the driver reactor is using `IO.select`, the maximum number of tcp connections allowed is 1024.
|
196
201
|
* Because the driver uses `IO#write_nonblock`, Windows is not supported.
|
data/lib/cassandra.rb
CHANGED
@@ -34,8 +34,10 @@ require 'date'
|
|
34
34
|
|
35
35
|
module Cassandra
|
36
36
|
# A list of all supported request consistencies
|
37
|
-
# @see http://www.datastax.com/documentation/cassandra/2.0/cassandra/dml/dml_config_consistency_c.html Consistency
|
38
|
-
#
|
37
|
+
# @see http://www.datastax.com/documentation/cassandra/2.0/cassandra/dml/dml_config_consistency_c.html Consistency
|
38
|
+
# levels in Apache Cassandra 2.0
|
39
|
+
# @see http://www.datastax.com/documentation/cassandra/1.2/cassandra/dml/dml_config_consistency_c.html Consistency
|
40
|
+
# levels in Apache Cassandra 1.2
|
39
41
|
# @see Cassandra::Session#execute_async
|
40
42
|
CONSISTENCIES = [:any, :one, :two, :three, :quorum, :all, :local_quorum,
|
41
43
|
:each_quorum, :serial, :local_serial, :local_one].freeze
|
@@ -47,9 +49,52 @@ module Cassandra
|
|
47
49
|
# A list of all possible write types that a
|
48
50
|
# {Cassandra::Errors::WriteTimeoutError} can have.
|
49
51
|
#
|
50
|
-
# @see https://github.com/apache/cassandra/blob/cassandra-2.0.16/doc/native_protocol_v2.spec#L872-L887 Description of
|
52
|
+
# @see https://github.com/apache/cassandra/blob/cassandra-2.0.16/doc/native_protocol_v2.spec#L872-L887 Description of
|
53
|
+
# possible types of writes in Apache Cassandra native protocol spec v1
|
51
54
|
WRITE_TYPES = [:simple, :batch, :unlogged_batch, :counter, :batch_log].freeze
|
52
55
|
|
56
|
+
CLUSTER_OPTIONS = [
|
57
|
+
:address_resolution,
|
58
|
+
:address_resolution_policy,
|
59
|
+
:auth_provider,
|
60
|
+
:client_cert,
|
61
|
+
:client_timestamps,
|
62
|
+
:compression,
|
63
|
+
:compressor,
|
64
|
+
:connect_timeout,
|
65
|
+
:connections_per_local_node,
|
66
|
+
:connections_per_remote_node,
|
67
|
+
:consistency,
|
68
|
+
:credentials,
|
69
|
+
:datacenter,
|
70
|
+
:futures_factory,
|
71
|
+
:heartbeat_interval,
|
72
|
+
:hosts,
|
73
|
+
:idle_timeout,
|
74
|
+
:listeners,
|
75
|
+
:load_balancing_policy,
|
76
|
+
:logger,
|
77
|
+
:nodelay,
|
78
|
+
:reconnection_policy,
|
79
|
+
:retry_policy,
|
80
|
+
:page_size,
|
81
|
+
:passphrase,
|
82
|
+
:password,
|
83
|
+
:port,
|
84
|
+
:private_key,
|
85
|
+
:protocol_version,
|
86
|
+
:requests_per_connection,
|
87
|
+
:schema_refresh_delay,
|
88
|
+
:schema_refresh_timeout,
|
89
|
+
:server_cert,
|
90
|
+
:shuffle_replicas,
|
91
|
+
:ssl,
|
92
|
+
:synchronize_schema,
|
93
|
+
:timeout,
|
94
|
+
:trace,
|
95
|
+
:username
|
96
|
+
].freeze
|
97
|
+
|
53
98
|
# Creates a {Cassandra::Cluster Cluster instance}.
|
54
99
|
#
|
55
100
|
# @option options [Array<String, IPAddr>] :hosts (['127.0.0.1']) a list of
|
@@ -141,6 +186,10 @@ module Cassandra
|
|
141
186
|
# for nodes that use the v3 or later protocol, and `128` for nodes that use the
|
142
187
|
# v2 or earlier protocol.
|
143
188
|
#
|
189
|
+
# @option options [Integer] :protocol_version (nil) Version of protocol to speak to
|
190
|
+
# nodes. By default, this is auto-negotiated to the lowest common protocol version
|
191
|
+
# that all nodes in `:hosts` speak.
|
192
|
+
#
|
144
193
|
# @option options [Boolean] :client_timestamps (false) whether the driver
|
145
194
|
# should send timestamps for each executed statement. Enabling this setting
|
146
195
|
# allows mitigating Cassandra cluster clock skew because the timestamp of
|
@@ -274,49 +323,13 @@ module Cassandra
|
|
274
323
|
# @private
|
275
324
|
SSL_CLASSES = [::TrueClass, ::FalseClass, ::OpenSSL::SSL::SSLContext].freeze
|
276
325
|
|
326
|
+
# rubocop:disable Metrics/AbcSize
|
327
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
328
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
277
329
|
# @private
|
278
330
|
def self.validate_and_massage_options(options)
|
279
331
|
options = options.select do |key, _|
|
280
|
-
|
281
|
-
:address_resolution,
|
282
|
-
:address_resolution_policy,
|
283
|
-
:auth_provider,
|
284
|
-
:client_cert,
|
285
|
-
:client_timestamps,
|
286
|
-
:compression,
|
287
|
-
:compressor,
|
288
|
-
:connect_timeout,
|
289
|
-
:connections_per_local_node,
|
290
|
-
:connections_per_remote_node,
|
291
|
-
:consistency,
|
292
|
-
:credentials,
|
293
|
-
:datacenter,
|
294
|
-
:futures_factory,
|
295
|
-
:heartbeat_interval,
|
296
|
-
:hosts,
|
297
|
-
:idle_timeout,
|
298
|
-
:listeners,
|
299
|
-
:load_balancing_policy,
|
300
|
-
:logger,
|
301
|
-
:nodelay,
|
302
|
-
:reconnection_policy,
|
303
|
-
:retry_policy,
|
304
|
-
:page_size,
|
305
|
-
:passphrase,
|
306
|
-
:password,
|
307
|
-
:port,
|
308
|
-
:private_key,
|
309
|
-
:requests_per_connection,
|
310
|
-
:schema_refresh_delay,
|
311
|
-
:schema_refresh_timeout,
|
312
|
-
:server_cert,
|
313
|
-
:shuffle_replicas,
|
314
|
-
:ssl,
|
315
|
-
:synchronize_schema,
|
316
|
-
:timeout,
|
317
|
-
:trace,
|
318
|
-
:username
|
319
|
-
].include?(key)
|
332
|
+
CLUSTER_OPTIONS.include?(key)
|
320
333
|
end
|
321
334
|
|
322
335
|
has_username = options.key?(:username)
|
@@ -608,12 +621,8 @@ module Cassandra
|
|
608
621
|
end
|
609
622
|
|
610
623
|
options[:nodelay] = !!options[:nodelay] if options.key?(:nodelay)
|
611
|
-
|
612
624
|
options[:trace] = !!options[:trace] if options.key?(:trace)
|
613
|
-
|
614
|
-
if options.key?(:shuffle_replicas)
|
615
|
-
options[:shuffle_replicas] = !!options[:shuffle_replicas]
|
616
|
-
end
|
625
|
+
options[:shuffle_replicas] = !!options[:shuffle_replicas] if options.key?(:shuffle_replicas)
|
617
626
|
|
618
627
|
if options.key?(:page_size)
|
619
628
|
page_size = options[:page_size]
|
@@ -627,6 +636,16 @@ module Cassandra
|
|
627
636
|
end
|
628
637
|
end
|
629
638
|
|
639
|
+
if options.key?(:protocol_version)
|
640
|
+
protocol_version = options[:protocol_version]
|
641
|
+
unless protocol_version.nil?
|
642
|
+
Util.assert_instance_of(::Integer, protocol_version)
|
643
|
+
Util.assert_one_of(1..4, protocol_version) do
|
644
|
+
":protocol_version must be a positive integer, #{protocol_version.inspect} given"
|
645
|
+
end
|
646
|
+
end
|
647
|
+
end
|
648
|
+
|
630
649
|
if options.key?(:futures_factory)
|
631
650
|
futures_factory = options[:futures_factory]
|
632
651
|
methods = [:error, :value, :promise, :all]
|
@@ -662,13 +681,8 @@ module Cassandra
|
|
662
681
|
end
|
663
682
|
end
|
664
683
|
|
665
|
-
if options.key?(:synchronize_schema)
|
666
|
-
|
667
|
-
end
|
668
|
-
|
669
|
-
if options.key?(:client_timestamps)
|
670
|
-
options[:client_timestamps] = !!options[:client_timestamps]
|
671
|
-
end
|
684
|
+
options[:synchronize_schema] = !!options[:synchronize_schema] if options.key?(:synchronize_schema)
|
685
|
+
options[:client_timestamps] = !!options[:client_timestamps] if options.key?(:client_timestamps)
|
672
686
|
|
673
687
|
if options.key?(:connections_per_local_node)
|
674
688
|
connections_per_node = options[:connections_per_local_node]
|
@@ -733,6 +747,8 @@ module Cassandra
|
|
733
747
|
DATE_OFFSET = (::Time.utc(1970, 1, 1).to_date.jd - 2**31)
|
734
748
|
end
|
735
749
|
|
750
|
+
require 'cassandra/attr_boolean'
|
751
|
+
require 'cassandra/version'
|
736
752
|
require 'cassandra/uuid'
|
737
753
|
require 'cassandra/time_uuid'
|
738
754
|
require 'cassandra/tuple'
|
@@ -763,8 +779,11 @@ require 'cassandra/argument'
|
|
763
779
|
require 'cassandra/function'
|
764
780
|
require 'cassandra/function_collection'
|
765
781
|
require 'cassandra/column'
|
782
|
+
require 'cassandra/column_container'
|
766
783
|
require 'cassandra/table'
|
784
|
+
require 'cassandra/materialized_view'
|
767
785
|
require 'cassandra/keyspace'
|
786
|
+
require 'cassandra/index'
|
768
787
|
|
769
788
|
require 'cassandra/execution/info'
|
770
789
|
require 'cassandra/execution/options'
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Copyright 2013-2016 DataStax, Inc.
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#++
|
18
|
+
|
19
|
+
# This file monkey-patches Module to have an attr_boolean method to make it easy
|
20
|
+
# for classes to define boolean instance variables with "foo?" reader methods.
|
21
|
+
# Inspired by http://stackoverflow.com/questions/4013591/attr-reader-with-question-mark-in-a-name
|
22
|
+
module Cassandra
|
23
|
+
module AttrBoolean
|
24
|
+
def attr_boolean(*names)
|
25
|
+
names.each do |name|
|
26
|
+
define_method(:"#{name}?") do
|
27
|
+
res = instance_variable_get(:"@#{name}")
|
28
|
+
!res.nil? && res != false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/cassandra/auth.rb
CHANGED
@@ -59,7 +59,8 @@ module Cassandra
|
|
59
59
|
# subclasses of this class, but need to implement the same methods. This
|
60
60
|
# class exists only for documentation purposes.
|
61
61
|
#
|
62
|
-
# @see https://github.com/apache/cassandra/blob/cassandra-2.0.16/doc/native_protocol_v2.spec#L257-L273 Cassandra
|
62
|
+
# @see https://github.com/apache/cassandra/blob/cassandra-2.0.16/doc/native_protocol_v2.spec#L257-L273 Cassandra
|
63
|
+
# native protocol v2 SASL authentication
|
63
64
|
# @see Cassandra::Auth::Provider#create_authenticator
|
64
65
|
class Authenticator
|
65
66
|
# @!method initial_response
|
@@ -53,24 +53,12 @@ module Cassandra
|
|
53
53
|
@password = password
|
54
54
|
end
|
55
55
|
|
56
|
-
# Returns a Password Authenticator
|
57
|
-
#
|
58
|
-
# @
|
59
|
-
# `org.apache.cassandra.auth.PasswordAuthenticator`
|
60
|
-
# @return [Cassandra::Auth::Authenticator] when `authentication_class ==
|
61
|
-
# "org.apache.cassandra.auth.PasswordAuthenticator"`
|
62
|
-
# @return [nil] for all other values of `authentication_class`
|
56
|
+
# Returns a Password Authenticator
|
57
|
+
# @param authentication_class [String] ignored
|
58
|
+
# @return [Cassandra::Auth::Authenticator]
|
63
59
|
def create_authenticator(authentication_class)
|
64
|
-
|
65
|
-
Authenticator.new(@username, @password)
|
66
|
-
end
|
60
|
+
Authenticator.new(@username, @password)
|
67
61
|
end
|
68
|
-
|
69
|
-
private
|
70
|
-
|
71
|
-
# @private
|
72
|
-
PASSWORD_AUTHENTICATOR_FQCN =
|
73
|
-
'org.apache.cassandra.auth.PasswordAuthenticator'.freeze
|
74
62
|
end
|
75
63
|
end
|
76
64
|
end
|
@@ -136,6 +136,7 @@ module Cassandra
|
|
136
136
|
@connection_options.idle_timeout,
|
137
137
|
@connection_options.requests_per_connection)
|
138
138
|
end.flat_map do |connection|
|
139
|
+
# connection is a CqlProtocolHandler
|
139
140
|
f = request_options(connection)
|
140
141
|
f = f.flat_map do |options|
|
141
142
|
compression = @connection_options.compression
|
@@ -159,10 +160,19 @@ module Cassandra
|
|
159
160
|
case error
|
160
161
|
when Errors::ProtocolError
|
161
162
|
synchronize do
|
162
|
-
|
163
|
+
current_version = connection.protocol_version
|
164
|
+
if current_version > 1 && @connection_options.protocol_negotiable?
|
163
165
|
@logger.info("Host #{host.ip} doesn't support protocol version " \
|
164
|
-
"#{
|
165
|
-
|
166
|
+
"#{current_version}, downgrading")
|
167
|
+
|
168
|
+
# This is tricky. We want to try with the next lower protocol version.
|
169
|
+
# However, the connection_options used for all connections may have
|
170
|
+
# already been updated due to other node connection failures. So,
|
171
|
+
# it may already have a lower protocol-version than our current-1. We
|
172
|
+
# don't want to accidentally raise it, so we update it to the min
|
173
|
+
# of itself and current-1.
|
174
|
+
@connection_options.protocol_version =
|
175
|
+
[@connection_options.protocol_version, current_version - 1].min
|
166
176
|
do_connect(host)
|
167
177
|
else
|
168
178
|
Ione::Future.failed(error)
|
@@ -170,7 +180,7 @@ module Cassandra
|
|
170
180
|
end
|
171
181
|
when Errors::TimeoutError
|
172
182
|
future = Ione::CompletableFuture.new
|
173
|
-
connection.close(error).on_complete do |
|
183
|
+
connection.close(error).on_complete do |_|
|
174
184
|
future.fail(error)
|
175
185
|
end
|
176
186
|
future
|
@@ -147,20 +147,20 @@ module Cassandra
|
|
147
147
|
private
|
148
148
|
|
149
149
|
SELECT_LOCAL = Protocol::QueryRequest.new(
|
150
|
-
'SELECT
|
150
|
+
'SELECT * ' \
|
151
151
|
'FROM system.local',
|
152
152
|
EMPTY_LIST,
|
153
153
|
EMPTY_LIST,
|
154
154
|
:one)
|
155
155
|
SELECT_PEERS = Protocol::QueryRequest.new(
|
156
|
-
'SELECT
|
156
|
+
'SELECT * ' \
|
157
157
|
'FROM system.peers',
|
158
158
|
EMPTY_LIST,
|
159
159
|
EMPTY_LIST,
|
160
160
|
:one)
|
161
161
|
|
162
162
|
SELECT_PEER_QUERY =
|
163
|
-
'SELECT
|
163
|
+
'SELECT * ' \
|
164
164
|
'FROM system.peers ' \
|
165
165
|
"WHERE peer = '%s'".freeze
|
166
166
|
|
@@ -191,18 +191,14 @@ module Cassandra
|
|
191
191
|
def register_async
|
192
192
|
connection = @connection
|
193
193
|
|
194
|
-
if connection.nil?
|
195
|
-
return Ione::Future.failed(Errors::ClientError.new('Not connected'))
|
196
|
-
end
|
194
|
+
return Ione::Future.failed(Errors::ClientError.new('Not connected')) if connection.nil?
|
197
195
|
|
198
196
|
request = Protocol::RegisterRequest.new(
|
199
197
|
Protocol::TopologyChangeEventResponse::TYPE,
|
200
198
|
Protocol::StatusChangeEventResponse::TYPE
|
201
199
|
)
|
202
200
|
|
203
|
-
if @connection_options.synchronize_schema?
|
204
|
-
request.events << Protocol::SchemaChangeEventResponse::TYPE
|
205
|
-
end
|
201
|
+
request.events << Protocol::SchemaChangeEventResponse::TYPE if @connection_options.synchronize_schema?
|
206
202
|
|
207
203
|
f = connection.send_request(request)
|
208
204
|
f = f.map do |r|
|
@@ -257,9 +253,7 @@ module Cassandra
|
|
257
253
|
|
258
254
|
@logger.info('Refreshing schema')
|
259
255
|
|
260
|
-
if connection.nil?
|
261
|
-
return Ione::Future.failed(Errors::ClientError.new('Not connected'))
|
262
|
-
end
|
256
|
+
return Ione::Future.failed(Errors::ClientError.new('Not connected')) if connection.nil?
|
263
257
|
|
264
258
|
@schema_fetcher.fetch(connection).map do |keyspaces|
|
265
259
|
@schema.replace(keyspaces)
|
@@ -271,9 +265,7 @@ module Cassandra
|
|
271
265
|
def refresh_keyspace_async(keyspace_name)
|
272
266
|
connection = @connection
|
273
267
|
|
274
|
-
if connection.nil?
|
275
|
-
return Ione::Future.failed(Errors::ClientError.new('Not connected'))
|
276
|
-
end
|
268
|
+
return Ione::Future.failed(Errors::ClientError.new('Not connected')) if connection.nil?
|
277
269
|
|
278
270
|
@logger.info("Refreshing keyspace \"#{keyspace_name}\"")
|
279
271
|
|
@@ -284,16 +276,14 @@ module Cassandra
|
|
284
276
|
@schema.delete_keyspace(keyspace_name)
|
285
277
|
end
|
286
278
|
|
287
|
-
@logger.info("
|
279
|
+
@logger.info("Completed refreshing keyspace \"#{keyspace_name}\"")
|
288
280
|
end
|
289
281
|
end
|
290
282
|
|
291
283
|
def refresh_table_async(keyspace_name, table_name)
|
292
284
|
connection = @connection
|
293
285
|
|
294
|
-
if connection.nil?
|
295
|
-
return Ione::Future.failed(Errors::ClientError.new('Not connected'))
|
296
|
-
end
|
286
|
+
return Ione::Future.failed(Errors::ClientError.new('Not connected')) if connection.nil?
|
297
287
|
|
298
288
|
@logger.info("Refreshing table \"#{keyspace_name}.#{table_name}\"")
|
299
289
|
|
@@ -304,16 +294,32 @@ module Cassandra
|
|
304
294
|
@schema.delete_table(keyspace_name, table_name)
|
305
295
|
end
|
306
296
|
|
307
|
-
@logger.info("
|
297
|
+
@logger.info("Completed refreshing table \"#{keyspace_name}.#{table_name}\"")
|
308
298
|
end
|
309
299
|
end
|
310
300
|
|
311
|
-
def
|
301
|
+
def refresh_materialized_view_async(keyspace_name, view_name)
|
312
302
|
connection = @connection
|
313
303
|
|
314
|
-
if connection.nil?
|
315
|
-
|
304
|
+
return Ione::Future.failed(Errors::ClientError.new('Not connected')) if connection.nil?
|
305
|
+
|
306
|
+
@logger.info("Refreshing materialized view \"#{keyspace_name}.#{view_name}\"")
|
307
|
+
|
308
|
+
@schema_fetcher.fetch_materialized_view(connection, keyspace_name, view_name).map do |view|
|
309
|
+
if view
|
310
|
+
@schema.replace_materialized_view(view)
|
311
|
+
else
|
312
|
+
@schema.delete_materialized_view(keyspace_name, view_name)
|
313
|
+
end
|
314
|
+
|
315
|
+
@logger.info("Completed refreshing materialized view \"#{keyspace_name}.#{view_name}\"")
|
316
316
|
end
|
317
|
+
end
|
318
|
+
|
319
|
+
def refresh_type_async(keyspace_name, type_name)
|
320
|
+
connection = @connection
|
321
|
+
|
322
|
+
return Ione::Future.failed(Errors::ClientError.new('Not connected')) if connection.nil?
|
317
323
|
|
318
324
|
@logger.info("Refreshing user-defined type \"#{keyspace_name}.#{type_name}\"")
|
319
325
|
|
@@ -324,16 +330,14 @@ module Cassandra
|
|
324
330
|
@schema.delete_type(keyspace_name, type_name)
|
325
331
|
end
|
326
332
|
|
327
|
-
@logger.info("
|
333
|
+
@logger.info("Completed refreshing user-defined type \"#{keyspace_name}.#{type_name}\"")
|
328
334
|
end
|
329
335
|
end
|
330
336
|
|
331
337
|
def refresh_function_async(keyspace_name, function_name, function_args)
|
332
338
|
connection = @connection
|
333
339
|
|
334
|
-
if connection.nil?
|
335
|
-
return Ione::Future.failed(Errors::ClientError.new('Not connected'))
|
336
|
-
end
|
340
|
+
return Ione::Future.failed(Errors::ClientError.new('Not connected')) if connection.nil?
|
337
341
|
|
338
342
|
@logger.info('Refreshing user-defined function ' \
|
339
343
|
"\"#{keyspace_name}.#{function_name}\"")
|
@@ -351,7 +355,7 @@ module Cassandra
|
|
351
355
|
@schema.delete_function(keyspace_name, function_name, parsed_function_args)
|
352
356
|
end
|
353
357
|
|
354
|
-
@logger.info('
|
358
|
+
@logger.info('Completed refreshing user-defined function ' \
|
355
359
|
"\"#{keyspace_name}.#{function_name}(#{function_args.join(',')})\"")
|
356
360
|
end
|
357
361
|
end
|
@@ -359,9 +363,7 @@ module Cassandra
|
|
359
363
|
def refresh_aggregate_async(keyspace_name, aggregate_name, aggregate_args)
|
360
364
|
connection = @connection
|
361
365
|
|
362
|
-
if connection.nil?
|
363
|
-
return Ione::Future.failed(Errors::ClientError.new('Not connected'))
|
364
|
-
end
|
366
|
+
return Ione::Future.failed(Errors::ClientError.new('Not connected')) if connection.nil?
|
365
367
|
|
366
368
|
@logger.info('Refreshing user-defined aggregate ' \
|
367
369
|
"\"#{keyspace_name}.#{aggregate_name}\"")
|
@@ -380,7 +382,7 @@ module Cassandra
|
|
380
382
|
@schema.delete_aggregate(keyspace_name, aggregate_name, parsed_aggregate_args)
|
381
383
|
end
|
382
384
|
|
383
|
-
@logger.info('
|
385
|
+
@logger.info('Completed refreshing user-defined aggregate ' \
|
384
386
|
"\"#{keyspace_name}.#{aggregate_name}(#{aggregate_args.join(',')})\"")
|
385
387
|
end
|
386
388
|
end
|
@@ -432,9 +434,7 @@ module Cassandra
|
|
432
434
|
def refresh_peers_async
|
433
435
|
connection = @connection
|
434
436
|
|
435
|
-
if connection.nil?
|
436
|
-
return Ione::Future.failed(Errors::ClientError.new('Not connected'))
|
437
|
-
end
|
437
|
+
return Ione::Future.failed(Errors::ClientError.new('Not connected')) if connection.nil?
|
438
438
|
|
439
439
|
@logger.info('Refreshing peers metadata')
|
440
440
|
|
@@ -456,7 +456,7 @@ module Cassandra
|
|
456
456
|
@registry.host_lost(host.ip) unless ips.include?(host.ip)
|
457
457
|
end
|
458
458
|
|
459
|
-
@logger.info('
|
459
|
+
@logger.info('Completed refreshing peers metadata')
|
460
460
|
|
461
461
|
nil
|
462
462
|
end
|
@@ -465,22 +465,18 @@ module Cassandra
|
|
465
465
|
def refresh_metadata_async
|
466
466
|
connection = @connection
|
467
467
|
|
468
|
-
if connection.nil?
|
469
|
-
return Ione::Future.failed(Errors::ClientError.new('Not connected'))
|
470
|
-
end
|
468
|
+
return Ione::Future.failed(Errors::ClientError.new('Not connected')) if connection.nil?
|
471
469
|
|
472
470
|
@logger.info("Refreshing connected host's metadata")
|
473
471
|
|
474
472
|
send_select_request(connection, SELECT_LOCAL).map do |local|
|
475
|
-
if local.empty?
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
@metadata.update(data)
|
481
|
-
end
|
473
|
+
raise Errors::InternalError, "Unable to fetch connected host's metadata" if local.empty?
|
474
|
+
|
475
|
+
data = local.first
|
476
|
+
@registry.host_found(IPAddr.new(connection.host), data)
|
477
|
+
@metadata.update(data)
|
482
478
|
|
483
|
-
@logger.info("
|
479
|
+
@logger.info("Completed refreshing connected host's metadata")
|
484
480
|
|
485
481
|
nil
|
486
482
|
end
|
@@ -559,9 +555,7 @@ module Cassandra
|
|
559
555
|
|
560
556
|
def refresh_host_async(address)
|
561
557
|
connection = @connection
|
562
|
-
if connection.nil?
|
563
|
-
return Ione::Future.failed(Errors::ClientError.new('Not connected'))
|
564
|
-
end
|
558
|
+
return Ione::Future.failed(Errors::ClientError.new('Not connected')) if connection.nil?
|
565
559
|
|
566
560
|
ip = address.to_s
|
567
561
|
|
@@ -577,12 +571,10 @@ module Cassandra
|
|
577
571
|
end
|
578
572
|
|
579
573
|
send_select_request(connection, request).map do |rows|
|
580
|
-
if rows.empty?
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
@registry.host_found(address, rows.first)
|
585
|
-
end
|
574
|
+
raise Errors::InternalError, "Unable to find host metadata: #{ip}" if rows.empty?
|
575
|
+
|
576
|
+
@logger.info("Completed refreshing host metadata: #{ip}")
|
577
|
+
@registry.host_found(address, rows.first)
|
586
578
|
|
587
579
|
self
|
588
580
|
end
|
@@ -647,9 +639,7 @@ Control connection failed and is unlikely to recover.
|
|
647
639
|
end
|
648
640
|
f = f.flat_map { register_async }
|
649
641
|
f = f.flat_map { refresh_peers_async_maybe_retry }
|
650
|
-
if @connection_options.synchronize_schema?
|
651
|
-
f = f.flat_map { refresh_maybe_retry(:schema) }
|
652
|
-
end
|
642
|
+
f = f.flat_map { refresh_maybe_retry(:schema) } if @connection_options.synchronize_schema?
|
653
643
|
f = f.fallback do |error|
|
654
644
|
@logger.debug("Connection to #{host.ip} failed " \
|
655
645
|
"(#{error.class.name}: #{error.message})")
|
@@ -683,8 +673,8 @@ Control connection failed and is unlikely to recover.
|
|
683
673
|
end
|
684
674
|
|
685
675
|
def process_schema_changes(schema_changes)
|
686
|
-
refresh_keyspaces
|
687
|
-
|
676
|
+
refresh_keyspaces = ::Hash.new
|
677
|
+
refresh_tables_and_views = ::Hash.new
|
688
678
|
refresh_types = ::Hash.new
|
689
679
|
|
690
680
|
# This hash is of the form <keyspace, [Change (for function changes)]>
|
@@ -700,14 +690,15 @@ Control connection failed and is unlikely to recover.
|
|
700
690
|
|
701
691
|
case change.target
|
702
692
|
when Protocol::Constants::SCHEMA_CHANGE_TARGET_KEYSPACE
|
703
|
-
|
693
|
+
refresh_tables_and_views.delete(keyspace)
|
704
694
|
refresh_types.delete(keyspace)
|
705
695
|
refresh_functions.delete(keyspace)
|
706
696
|
refresh_aggregates.delete(keyspace)
|
707
697
|
refresh_keyspaces[keyspace] = true
|
708
698
|
when Protocol::Constants::SCHEMA_CHANGE_TARGET_TABLE
|
709
|
-
|
710
|
-
|
699
|
+
# We can't distinguish between table and view change events, so refresh both.
|
700
|
+
tables_and_views = refresh_tables_and_views[keyspace] ||= ::Hash.new
|
701
|
+
tables_and_views[change.name] = true
|
711
702
|
when Protocol::Constants::SCHEMA_CHANGE_TARGET_UDT
|
712
703
|
types = refresh_types[keyspace] ||= ::Hash.new
|
713
704
|
types[change.name] = true
|
@@ -726,9 +717,10 @@ Control connection failed and is unlikely to recover.
|
|
726
717
|
futures << refresh_maybe_retry(:keyspace, keyspace)
|
727
718
|
end
|
728
719
|
|
729
|
-
|
730
|
-
|
731
|
-
futures << refresh_maybe_retry(:table, keyspace,
|
720
|
+
refresh_tables_and_views.each do |(keyspace, tables_and_views)|
|
721
|
+
tables_and_views.each_key do |table_or_view|
|
722
|
+
futures << refresh_maybe_retry(:table, keyspace, table_or_view)
|
723
|
+
futures << refresh_maybe_retry(:materialized_view, keyspace, table_or_view)
|
732
724
|
end
|
733
725
|
end
|
734
726
|
|