yugabyte-ycql-driver 3.2.3.1
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 +7 -0
- data/.yardopts +13 -0
- data/README.md +242 -0
- data/ext/cassandra_murmur3/cassandra_murmur3.c +178 -0
- data/ext/cassandra_murmur3/extconf.rb +2 -0
- data/lib/cassandra/address_resolution.rb +36 -0
- data/lib/cassandra/address_resolution/policies.rb +2 -0
- data/lib/cassandra/address_resolution/policies/ec2_multi_region.rb +56 -0
- data/lib/cassandra/address_resolution/policies/none.rb +35 -0
- data/lib/cassandra/aggregate.rb +123 -0
- data/lib/cassandra/argument.rb +51 -0
- data/lib/cassandra/attr_boolean.rb +33 -0
- data/lib/cassandra/auth.rb +100 -0
- data/lib/cassandra/auth/providers.rb +17 -0
- data/lib/cassandra/auth/providers/password.rb +65 -0
- data/lib/cassandra/cassandra_logger.rb +80 -0
- data/lib/cassandra/cluster.rb +331 -0
- data/lib/cassandra/cluster/client.rb +1612 -0
- data/lib/cassandra/cluster/connection_pool.rb +78 -0
- data/lib/cassandra/cluster/connector.rb +372 -0
- data/lib/cassandra/cluster/control_connection.rb +962 -0
- data/lib/cassandra/cluster/failed_connection.rb +35 -0
- data/lib/cassandra/cluster/metadata.rb +142 -0
- data/lib/cassandra/cluster/options.rb +145 -0
- data/lib/cassandra/cluster/registry.rb +284 -0
- data/lib/cassandra/cluster/schema.rb +405 -0
- data/lib/cassandra/cluster/schema/cql_type_parser.rb +112 -0
- data/lib/cassandra/cluster/schema/fetchers.rb +1627 -0
- data/lib/cassandra/cluster/schema/fqcn_type_parser.rb +175 -0
- data/lib/cassandra/cluster/schema/partitioners.rb +21 -0
- data/lib/cassandra/cluster/schema/partitioners/murmur3.rb +45 -0
- data/lib/cassandra/cluster/schema/partitioners/ordered.rb +37 -0
- data/lib/cassandra/cluster/schema/partitioners/random.rb +37 -0
- data/lib/cassandra/cluster/schema/replication_strategies.rb +21 -0
- data/lib/cassandra/cluster/schema/replication_strategies/network_topology.rb +102 -0
- data/lib/cassandra/cluster/schema/replication_strategies/none.rb +39 -0
- data/lib/cassandra/cluster/schema/replication_strategies/simple.rb +44 -0
- data/lib/cassandra/column.rb +66 -0
- data/lib/cassandra/column_container.rb +326 -0
- data/lib/cassandra/compression.rb +69 -0
- data/lib/cassandra/compression/compressors/lz4.rb +73 -0
- data/lib/cassandra/compression/compressors/snappy.rb +69 -0
- data/lib/cassandra/custom_data.rb +53 -0
- data/lib/cassandra/driver.rb +260 -0
- data/lib/cassandra/errors.rb +784 -0
- data/lib/cassandra/execution/info.rb +69 -0
- data/lib/cassandra/execution/options.rb +267 -0
- data/lib/cassandra/execution/profile.rb +153 -0
- data/lib/cassandra/execution/profile_manager.rb +71 -0
- data/lib/cassandra/execution/trace.rb +192 -0
- data/lib/cassandra/executors.rb +113 -0
- data/lib/cassandra/function.rb +156 -0
- data/lib/cassandra/function_collection.rb +85 -0
- data/lib/cassandra/future.rb +794 -0
- data/lib/cassandra/host.rb +102 -0
- data/lib/cassandra/index.rb +118 -0
- data/lib/cassandra/keyspace.rb +473 -0
- data/lib/cassandra/listener.rb +87 -0
- data/lib/cassandra/load_balancing.rb +121 -0
- data/lib/cassandra/load_balancing/policies.rb +20 -0
- data/lib/cassandra/load_balancing/policies/dc_aware_round_robin.rb +172 -0
- data/lib/cassandra/load_balancing/policies/round_robin.rb +141 -0
- data/lib/cassandra/load_balancing/policies/token_aware.rb +149 -0
- data/lib/cassandra/load_balancing/policies/white_list.rb +100 -0
- data/lib/cassandra/materialized_view.rb +92 -0
- data/lib/cassandra/null_logger.rb +56 -0
- data/lib/cassandra/protocol.rb +102 -0
- data/lib/cassandra/protocol/coder.rb +1085 -0
- data/lib/cassandra/protocol/cql_byte_buffer.rb +418 -0
- data/lib/cassandra/protocol/cql_protocol_handler.rb +448 -0
- data/lib/cassandra/protocol/request.rb +41 -0
- data/lib/cassandra/protocol/requests/auth_response_request.rb +51 -0
- data/lib/cassandra/protocol/requests/batch_request.rb +117 -0
- data/lib/cassandra/protocol/requests/credentials_request.rb +51 -0
- data/lib/cassandra/protocol/requests/execute_request.rb +122 -0
- data/lib/cassandra/protocol/requests/options_request.rb +39 -0
- data/lib/cassandra/protocol/requests/prepare_request.rb +59 -0
- data/lib/cassandra/protocol/requests/query_request.rb +112 -0
- data/lib/cassandra/protocol/requests/register_request.rb +38 -0
- data/lib/cassandra/protocol/requests/startup_request.rb +49 -0
- data/lib/cassandra/protocol/requests/void_query_request.rb +24 -0
- data/lib/cassandra/protocol/response.rb +28 -0
- data/lib/cassandra/protocol/responses/already_exists_error_response.rb +50 -0
- data/lib/cassandra/protocol/responses/auth_challenge_response.rb +36 -0
- data/lib/cassandra/protocol/responses/auth_success_response.rb +36 -0
- data/lib/cassandra/protocol/responses/authenticate_response.rb +36 -0
- data/lib/cassandra/protocol/responses/error_response.rb +142 -0
- data/lib/cassandra/protocol/responses/event_response.rb +30 -0
- data/lib/cassandra/protocol/responses/function_failure_error_response.rb +52 -0
- data/lib/cassandra/protocol/responses/prepared_result_response.rb +62 -0
- data/lib/cassandra/protocol/responses/raw_rows_result_response.rb +59 -0
- data/lib/cassandra/protocol/responses/read_failure_error_response.rb +71 -0
- data/lib/cassandra/protocol/responses/read_timeout_error_response.rb +61 -0
- data/lib/cassandra/protocol/responses/ready_response.rb +43 -0
- data/lib/cassandra/protocol/responses/result_response.rb +42 -0
- data/lib/cassandra/protocol/responses/rows_result_response.rb +39 -0
- data/lib/cassandra/protocol/responses/schema_change_event_response.rb +73 -0
- data/lib/cassandra/protocol/responses/schema_change_result_response.rb +70 -0
- data/lib/cassandra/protocol/responses/set_keyspace_result_response.rb +37 -0
- data/lib/cassandra/protocol/responses/status_change_event_response.rb +39 -0
- data/lib/cassandra/protocol/responses/supported_response.rb +36 -0
- data/lib/cassandra/protocol/responses/topology_change_event_response.rb +33 -0
- data/lib/cassandra/protocol/responses/unavailable_error_response.rb +58 -0
- data/lib/cassandra/protocol/responses/unprepared_error_response.rb +48 -0
- data/lib/cassandra/protocol/responses/void_result_response.rb +34 -0
- data/lib/cassandra/protocol/responses/write_failure_error_response.rb +73 -0
- data/lib/cassandra/protocol/responses/write_timeout_error_response.rb +63 -0
- data/lib/cassandra/protocol/v1.rb +326 -0
- data/lib/cassandra/protocol/v3.rb +358 -0
- data/lib/cassandra/protocol/v4.rb +478 -0
- data/lib/cassandra/reconnection.rb +49 -0
- data/lib/cassandra/reconnection/policies.rb +20 -0
- data/lib/cassandra/reconnection/policies/constant.rb +46 -0
- data/lib/cassandra/reconnection/policies/exponential.rb +79 -0
- data/lib/cassandra/result.rb +276 -0
- data/lib/cassandra/retry.rb +154 -0
- data/lib/cassandra/retry/policies.rb +21 -0
- data/lib/cassandra/retry/policies/default.rb +53 -0
- data/lib/cassandra/retry/policies/downgrading_consistency.rb +73 -0
- data/lib/cassandra/retry/policies/fallthrough.rb +39 -0
- data/lib/cassandra/session.rb +270 -0
- data/lib/cassandra/statement.rb +32 -0
- data/lib/cassandra/statements.rb +23 -0
- data/lib/cassandra/statements/batch.rb +146 -0
- data/lib/cassandra/statements/bound.rb +65 -0
- data/lib/cassandra/statements/prepared.rb +235 -0
- data/lib/cassandra/statements/simple.rb +118 -0
- data/lib/cassandra/statements/void.rb +38 -0
- data/lib/cassandra/table.rb +240 -0
- data/lib/cassandra/time.rb +103 -0
- data/lib/cassandra/time_uuid.rb +78 -0
- data/lib/cassandra/timestamp_generator.rb +37 -0
- data/lib/cassandra/timestamp_generator/simple.rb +38 -0
- data/lib/cassandra/timestamp_generator/ticking_on_duplicate.rb +58 -0
- data/lib/cassandra/trigger.rb +67 -0
- data/lib/cassandra/tuple.rb +131 -0
- data/lib/cassandra/types.rb +1704 -0
- data/lib/cassandra/udt.rb +443 -0
- data/lib/cassandra/util.rb +464 -0
- data/lib/cassandra/uuid.rb +110 -0
- data/lib/cassandra/uuid/generator.rb +212 -0
- data/lib/cassandra/version.rb +21 -0
- data/lib/datastax/cassandra.rb +47 -0
- data/lib/ycql.rb +842 -0
- metadata +243 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# Copyright 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
|
+
module Cassandra
|
|
20
|
+
class Cluster
|
|
21
|
+
# @private
|
|
22
|
+
class FailedConnection
|
|
23
|
+
attr_reader :error, :host
|
|
24
|
+
|
|
25
|
+
def initialize(error, host)
|
|
26
|
+
@error = error
|
|
27
|
+
@host = host
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def connected?
|
|
31
|
+
false
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# Copyright 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
|
+
module Cassandra
|
|
20
|
+
class Cluster
|
|
21
|
+
# @private
|
|
22
|
+
class Metadata
|
|
23
|
+
include MonitorMixin
|
|
24
|
+
|
|
25
|
+
attr_reader :name
|
|
26
|
+
|
|
27
|
+
def initialize(cluster_registry,
|
|
28
|
+
cluster_schema,
|
|
29
|
+
schema_partitioners,
|
|
30
|
+
replication_strategies,
|
|
31
|
+
default_replication_strategy)
|
|
32
|
+
@registry = cluster_registry
|
|
33
|
+
@schema = cluster_schema
|
|
34
|
+
@partitioners = schema_partitioners
|
|
35
|
+
@strategies = replication_strategies
|
|
36
|
+
@default_strategy = default_replication_strategy
|
|
37
|
+
@token_replicas = ::Hash.new
|
|
38
|
+
@token_ring = ::Array.new
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def find_replicas(keyspace, statement)
|
|
42
|
+
return EMPTY_LIST unless statement.respond_to?(:partition_key) && statement.respond_to?(:keyspace)
|
|
43
|
+
|
|
44
|
+
keyspace = String(statement.keyspace || keyspace)
|
|
45
|
+
partition_key = statement.partition_key
|
|
46
|
+
return EMPTY_LIST unless keyspace && partition_key
|
|
47
|
+
|
|
48
|
+
partitioner = @partitioner
|
|
49
|
+
return EMPTY_LIST unless partitioner
|
|
50
|
+
|
|
51
|
+
keyspace_hosts = @token_replicas[keyspace]
|
|
52
|
+
return EMPTY_LIST if keyspace_hosts.nil? || keyspace_hosts.empty?
|
|
53
|
+
|
|
54
|
+
token = partitioner.create_token(partition_key)
|
|
55
|
+
index = insertion_point(@token_ring, token)
|
|
56
|
+
index = 0 if index >= @token_ring.size
|
|
57
|
+
hosts = keyspace_hosts[@token_ring[index]]
|
|
58
|
+
return EMPTY_LIST unless hosts
|
|
59
|
+
|
|
60
|
+
hosts
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def update(data)
|
|
64
|
+
@name = data['cluster_name']
|
|
65
|
+
@partitioner = @partitioners[data['partitioner']]
|
|
66
|
+
|
|
67
|
+
self
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def rebuild_token_map
|
|
71
|
+
partitioner = @partitioner
|
|
72
|
+
return self unless partitioner
|
|
73
|
+
|
|
74
|
+
tokens = ::SortedSet.new
|
|
75
|
+
token_to_host = ::Hash.new
|
|
76
|
+
|
|
77
|
+
@registry.each_host do |host|
|
|
78
|
+
host.tokens.each do |token|
|
|
79
|
+
token = begin
|
|
80
|
+
partitioner.parse_token(token)
|
|
81
|
+
rescue
|
|
82
|
+
next
|
|
83
|
+
end
|
|
84
|
+
tokens.add(token)
|
|
85
|
+
token_to_host[token] = host
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
token_ring = tokens.to_a
|
|
90
|
+
token_replicas = ::Hash.new
|
|
91
|
+
token_maps = ::Hash.new
|
|
92
|
+
|
|
93
|
+
@schema.each_keyspace do |keyspace|
|
|
94
|
+
replication = keyspace.replication
|
|
95
|
+
key = replication_key(replication.klass, replication.options)
|
|
96
|
+
|
|
97
|
+
unless token_maps.include?(key)
|
|
98
|
+
strategy = @strategies[replication.klass] || @default_strategy
|
|
99
|
+
token_maps[key] = strategy.replication_map(
|
|
100
|
+
token_to_host,
|
|
101
|
+
token_ring,
|
|
102
|
+
replication.options
|
|
103
|
+
)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
token_replicas[keyspace.name] = token_maps[key]
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
@token_replicas = token_replicas
|
|
110
|
+
@token_ring = token_ring
|
|
111
|
+
|
|
112
|
+
self
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
private
|
|
116
|
+
|
|
117
|
+
def replication_key(klass, options)
|
|
118
|
+
(klass + ':' + options.keys.sort.map {|k| "#{k}=#{options[k]}"}.join(',')).hash
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def insertion_point(list, item)
|
|
122
|
+
min = 0
|
|
123
|
+
max = list.size - 1
|
|
124
|
+
|
|
125
|
+
while min <= max
|
|
126
|
+
idx = (min + max) / 2
|
|
127
|
+
val = list[idx]
|
|
128
|
+
|
|
129
|
+
if val < item
|
|
130
|
+
min = idx + 1
|
|
131
|
+
elsif val > item
|
|
132
|
+
max = idx - 1
|
|
133
|
+
else
|
|
134
|
+
return idx # item found
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
min # item not found.
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# Copyright 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
|
+
module Cassandra
|
|
20
|
+
class Cluster
|
|
21
|
+
# @private
|
|
22
|
+
class Options
|
|
23
|
+
extend AttrBoolean
|
|
24
|
+
|
|
25
|
+
attr_reader :auth_provider, :compressor, :connect_timeout, :credentials,
|
|
26
|
+
:heartbeat_interval, :idle_timeout, :port, :schema_refresh_delay,
|
|
27
|
+
:schema_refresh_timeout, :ssl, :custom_type_handlers
|
|
28
|
+
attr_boolean :protocol_negotiable, :synchronize_schema, :nodelay, :allow_beta_protocol
|
|
29
|
+
|
|
30
|
+
attr_accessor :protocol_version
|
|
31
|
+
|
|
32
|
+
def initialize(logger,
|
|
33
|
+
protocol_version,
|
|
34
|
+
credentials,
|
|
35
|
+
auth_provider,
|
|
36
|
+
compressor,
|
|
37
|
+
port,
|
|
38
|
+
connect_timeout,
|
|
39
|
+
ssl,
|
|
40
|
+
connections_per_local_node,
|
|
41
|
+
connections_per_remote_node,
|
|
42
|
+
heartbeat_interval,
|
|
43
|
+
idle_timeout,
|
|
44
|
+
synchronize_schema,
|
|
45
|
+
schema_refresh_delay,
|
|
46
|
+
schema_refresh_timeout,
|
|
47
|
+
nodelay,
|
|
48
|
+
requests_per_connection,
|
|
49
|
+
custom_types,
|
|
50
|
+
allow_beta_protocol)
|
|
51
|
+
@logger = logger
|
|
52
|
+
@protocol_version = protocol_version
|
|
53
|
+
@credentials = credentials
|
|
54
|
+
@auth_provider = auth_provider
|
|
55
|
+
@compressor = compressor
|
|
56
|
+
@port = port
|
|
57
|
+
@connect_timeout = connect_timeout
|
|
58
|
+
@ssl = ssl
|
|
59
|
+
@heartbeat_interval = heartbeat_interval
|
|
60
|
+
@idle_timeout = idle_timeout
|
|
61
|
+
@synchronize_schema = synchronize_schema
|
|
62
|
+
@schema_refresh_delay = schema_refresh_delay
|
|
63
|
+
@schema_refresh_timeout = schema_refresh_timeout
|
|
64
|
+
@nodelay = nodelay
|
|
65
|
+
@allow_beta_protocol = allow_beta_protocol
|
|
66
|
+
@custom_type_handlers = {}
|
|
67
|
+
custom_types.each do |type_klass|
|
|
68
|
+
@custom_type_handlers[type_klass.type] = type_klass
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
@connections_per_local_node = connections_per_local_node
|
|
72
|
+
@connections_per_remote_node = connections_per_remote_node
|
|
73
|
+
@requests_per_connection = requests_per_connection
|
|
74
|
+
|
|
75
|
+
# If @protocol_version is nil, it means we want the driver to negotiate the
|
|
76
|
+
# protocol starting with our known max. If @protocol_version is not nil,
|
|
77
|
+
# it means the user wants us to use a particular version, so we should not
|
|
78
|
+
# support negotiation.
|
|
79
|
+
|
|
80
|
+
@protocol_negotiable = @protocol_version.nil?
|
|
81
|
+
@protocol_version ||= allow_beta_protocol ?
|
|
82
|
+
Cassandra::Protocol::Versions::BETA_VERSION :
|
|
83
|
+
Cassandra::Protocol::Versions::MAX_SUPPORTED_VERSION
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def compression
|
|
87
|
+
@compressor && @compressor.algorithm
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def create_authenticator(authentication_class, host)
|
|
91
|
+
if @auth_provider
|
|
92
|
+
# Auth providers should take an auth-class and host, but they used to not, so for backward compatibility
|
|
93
|
+
# we figure out if this provider does, and if so send both args, otherwise just send the auth-class.
|
|
94
|
+
|
|
95
|
+
if @auth_provider.method(:create_authenticator).arity == 1
|
|
96
|
+
@auth_provider.create_authenticator(authentication_class)
|
|
97
|
+
else
|
|
98
|
+
@auth_provider.create_authenticator(authentication_class, host)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def connections_per_local_node
|
|
104
|
+
# Return the option if set.
|
|
105
|
+
return @connections_per_local_node if @connections_per_local_node
|
|
106
|
+
|
|
107
|
+
# For v3 and later, default is 1 local connection.
|
|
108
|
+
# For v2 and earlier, default is 2 local connections.
|
|
109
|
+
# Return the default
|
|
110
|
+
(@protocol_version > 2) ? 1 : 2
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def connections_per_remote_node
|
|
114
|
+
# Return the option if set; otherwise return the default (1).
|
|
115
|
+
@connections_per_remote_node || 1
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def requests_per_connection
|
|
119
|
+
# There are a few possibilities here based on @requests_per_connection:
|
|
120
|
+
# nil: default to 1024 for protocol 3 and later, 128 for < 3.
|
|
121
|
+
# we're in v2 and value too high: return 128. We don't worry
|
|
122
|
+
# about this case for v3+ because option validation in
|
|
123
|
+
# Cassandra::cluster_async takes care of that.
|
|
124
|
+
# good value: return it.
|
|
125
|
+
#
|
|
126
|
+
# NOTE: We can't compute and cache the result because protocol_version
|
|
127
|
+
# can change over time in theory (if all nodes are upgraded to a new
|
|
128
|
+
# version of Cassandra)
|
|
129
|
+
|
|
130
|
+
# Return the default if option wasn't specified.
|
|
131
|
+
default_requests_per_connection = @protocol_version > 2 ? 1024 : 128
|
|
132
|
+
return default_requests_per_connection unless @requests_per_connection
|
|
133
|
+
|
|
134
|
+
if @requests_per_connection > 128 && @protocol_version < 3
|
|
135
|
+
@logger.warn(
|
|
136
|
+
":requests_per_connection setting of #{@requests_per_connection} is more " \
|
|
137
|
+
'than the max of 128 for protocol v2. Falling back to 128.'
|
|
138
|
+
)
|
|
139
|
+
return 128
|
|
140
|
+
end
|
|
141
|
+
@requests_per_connection
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# Copyright 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
|
+
module Cassandra
|
|
20
|
+
class Cluster
|
|
21
|
+
# @private
|
|
22
|
+
class Registry
|
|
23
|
+
include MonitorMixin
|
|
24
|
+
|
|
25
|
+
def initialize(logger)
|
|
26
|
+
@logger = logger
|
|
27
|
+
@hosts = ::Hash.new
|
|
28
|
+
@listeners = ::Array.new
|
|
29
|
+
|
|
30
|
+
mon_initialize
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def add_listener(listener)
|
|
34
|
+
synchronize do
|
|
35
|
+
listeners = @listeners.dup
|
|
36
|
+
listeners.push(listener)
|
|
37
|
+
@listeners = listeners
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
self
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def remove_listener(listener)
|
|
44
|
+
synchronize do
|
|
45
|
+
listeners = @listeners.dup
|
|
46
|
+
listeners.delete(listener)
|
|
47
|
+
@listeners = listeners
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
self
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def each_host(&block)
|
|
54
|
+
if block_given?
|
|
55
|
+
@hosts.each_value(&block)
|
|
56
|
+
self
|
|
57
|
+
else
|
|
58
|
+
@hosts.values
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
alias hosts each_host
|
|
62
|
+
|
|
63
|
+
# @param address [IPAddr] resolved address of the node
|
|
64
|
+
def host(address)
|
|
65
|
+
@hosts[address.to_s]
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# @param address [IPAddr] resolved address of the node
|
|
69
|
+
def has_host?(address)
|
|
70
|
+
@hosts.key?(address.to_s)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# @param address [IPAddr] resolved address of the node
|
|
74
|
+
# @param data [Hash<String, String>] attributes of the host, typically a row from system.local or system.peers.
|
|
75
|
+
def host_found(address, data = {})
|
|
76
|
+
ip = address.to_s
|
|
77
|
+
host = @hosts[ip]
|
|
78
|
+
|
|
79
|
+
if host
|
|
80
|
+
if host.id == data['host_id'] &&
|
|
81
|
+
host.release_version == data['release_version'] &&
|
|
82
|
+
host.rack == data['rack'] &&
|
|
83
|
+
host.datacenter == data['data_center'] &&
|
|
84
|
+
host.broadcast_address == data['broadcast_address'] &&
|
|
85
|
+
host.listen_address == data['listen_address']
|
|
86
|
+
|
|
87
|
+
return self if host.up?
|
|
88
|
+
|
|
89
|
+
host = toggle_up(host)
|
|
90
|
+
else
|
|
91
|
+
@logger.debug("Host #{host.ip} metadata has been updated, it will be " \
|
|
92
|
+
'considered lost and found')
|
|
93
|
+
|
|
94
|
+
notify_lost(host)
|
|
95
|
+
|
|
96
|
+
host = create_host(address, data)
|
|
97
|
+
|
|
98
|
+
notify_found(host)
|
|
99
|
+
end
|
|
100
|
+
else
|
|
101
|
+
host = create_host(address, data)
|
|
102
|
+
|
|
103
|
+
notify_found(host)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
synchronize do
|
|
107
|
+
hosts = @hosts.dup
|
|
108
|
+
hosts[ip] = host
|
|
109
|
+
@hosts = hosts
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
self
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# @param address [IPAddr] resolved address of the node
|
|
116
|
+
def host_down(address)
|
|
117
|
+
ip = address.to_s
|
|
118
|
+
host = @hosts[ip]
|
|
119
|
+
|
|
120
|
+
return self unless host && !host.down?
|
|
121
|
+
|
|
122
|
+
host = toggle_down(host)
|
|
123
|
+
|
|
124
|
+
synchronize do
|
|
125
|
+
hosts = @hosts.dup
|
|
126
|
+
hosts[ip] = host
|
|
127
|
+
@hosts = hosts
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
self
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# @param address [IPAddr] resolved address of the node
|
|
134
|
+
def host_up(address)
|
|
135
|
+
ip = address.to_s
|
|
136
|
+
host = @hosts[ip]
|
|
137
|
+
|
|
138
|
+
return self unless host && !host.up?
|
|
139
|
+
|
|
140
|
+
host = toggle_up(host)
|
|
141
|
+
|
|
142
|
+
synchronize do
|
|
143
|
+
hosts = @hosts.dup
|
|
144
|
+
hosts[ip] = host
|
|
145
|
+
@hosts = hosts
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
self
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
# @param address [IPAddr] resolved address of the node
|
|
152
|
+
def host_lost(address)
|
|
153
|
+
ip = address.to_s
|
|
154
|
+
host = nil
|
|
155
|
+
|
|
156
|
+
return self unless @hosts.key?(ip)
|
|
157
|
+
|
|
158
|
+
synchronize do
|
|
159
|
+
hosts = @hosts.dup
|
|
160
|
+
host = hosts.delete(ip)
|
|
161
|
+
@hosts = hosts
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
notify_lost(host)
|
|
165
|
+
|
|
166
|
+
host
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
private
|
|
170
|
+
|
|
171
|
+
# @param ip [String] resolved address of the node
|
|
172
|
+
# @param data [Hash<String, String>] attributes of the host, typically a row from system.local or system.peers.
|
|
173
|
+
def create_host(ip, data)
|
|
174
|
+
Host.new(ip,
|
|
175
|
+
data['host_id'],
|
|
176
|
+
data['rack'],
|
|
177
|
+
data['data_center'],
|
|
178
|
+
data['release_version'],
|
|
179
|
+
Array(data['tokens']).freeze,
|
|
180
|
+
:up,
|
|
181
|
+
data['broadcast_address'],
|
|
182
|
+
data['listen_address'])
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# @param host [Host] host that is found to be up.
|
|
186
|
+
def toggle_up(host)
|
|
187
|
+
host = Host.new(host.ip,
|
|
188
|
+
host.id,
|
|
189
|
+
host.rack,
|
|
190
|
+
host.datacenter,
|
|
191
|
+
host.release_version,
|
|
192
|
+
host.tokens,
|
|
193
|
+
:up,
|
|
194
|
+
host.broadcast_address,
|
|
195
|
+
host.listen_address)
|
|
196
|
+
@logger.debug("Host #{host.ip} is up")
|
|
197
|
+
@listeners.each do |listener|
|
|
198
|
+
begin
|
|
199
|
+
listener.host_up(host)
|
|
200
|
+
rescue
|
|
201
|
+
nil
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
host
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# @param host [Host] host that is found to be down.
|
|
208
|
+
def toggle_down(host)
|
|
209
|
+
host = Host.new(host.ip,
|
|
210
|
+
host.id,
|
|
211
|
+
host.rack,
|
|
212
|
+
host.datacenter,
|
|
213
|
+
host.release_version,
|
|
214
|
+
host.tokens,
|
|
215
|
+
:down,
|
|
216
|
+
host.broadcast_address,
|
|
217
|
+
host.listen_address)
|
|
218
|
+
@logger.debug("Host #{host.ip} is down")
|
|
219
|
+
@listeners.reverse_each do |listener|
|
|
220
|
+
begin
|
|
221
|
+
listener.host_down(host)
|
|
222
|
+
rescue
|
|
223
|
+
nil
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
host
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
# @param host [Host] host that is lost.
|
|
230
|
+
def notify_lost(host)
|
|
231
|
+
if host.up?
|
|
232
|
+
@logger.debug("Host #{host.ip} is down and lost")
|
|
233
|
+
host = Host.new(host.ip,
|
|
234
|
+
host.id,
|
|
235
|
+
host.rack,
|
|
236
|
+
host.datacenter,
|
|
237
|
+
host.release_version,
|
|
238
|
+
host.tokens,
|
|
239
|
+
:down,
|
|
240
|
+
host.broadcast_address,
|
|
241
|
+
host.listen_address)
|
|
242
|
+
@listeners.reverse_each do |listener|
|
|
243
|
+
begin
|
|
244
|
+
listener.host_down(host)
|
|
245
|
+
rescue
|
|
246
|
+
nil
|
|
247
|
+
end
|
|
248
|
+
begin
|
|
249
|
+
listener.host_lost(host)
|
|
250
|
+
rescue
|
|
251
|
+
nil
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
else
|
|
255
|
+
@logger.debug("Host #{host.ip} is lost")
|
|
256
|
+
@listeners.reverse_each do |listener|
|
|
257
|
+
begin
|
|
258
|
+
listener.host_lost(host)
|
|
259
|
+
rescue
|
|
260
|
+
nil
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
# @param host [Host] host that is found.
|
|
267
|
+
def notify_found(host)
|
|
268
|
+
@logger.debug("Host #{host.ip} is found and up")
|
|
269
|
+
@listeners.each do |listener|
|
|
270
|
+
begin
|
|
271
|
+
listener.host_found(host)
|
|
272
|
+
rescue
|
|
273
|
+
nil
|
|
274
|
+
end
|
|
275
|
+
begin
|
|
276
|
+
listener.host_up(host)
|
|
277
|
+
rescue
|
|
278
|
+
nil
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
end
|