cassandra-driver 3.0.0.rc.1 → 3.0.0.rc.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Build Status](https://travis-ci.org/datastax/ruby-driver.svg?branch=master)](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
|
|