yugabyte-ycql-driver 3.2.3.1
Sign up to get free protection for your applications and to get access to all the features.
- 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,78 @@
|
|
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 ConnectionPool
|
23
|
+
include Enumerable
|
24
|
+
|
25
|
+
def initialize
|
26
|
+
@connections = []
|
27
|
+
@lock = ::Mutex.new
|
28
|
+
end
|
29
|
+
|
30
|
+
def add_connections(connections)
|
31
|
+
@lock.synchronize do
|
32
|
+
@connections.concat(connections)
|
33
|
+
connections.each do |connection|
|
34
|
+
connection.on_closed do
|
35
|
+
@lock.synchronize do
|
36
|
+
@connections.delete(connection)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def connected?
|
44
|
+
@lock.synchronize do
|
45
|
+
@connections.any?
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def snapshot
|
50
|
+
@lock.synchronize do
|
51
|
+
@connections.dup
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def random_connection
|
56
|
+
raise Errors::IOError, 'Not connected' unless connected?
|
57
|
+
@lock.synchronize do
|
58
|
+
@connections.sample
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def size
|
63
|
+
@lock.synchronize do
|
64
|
+
@connections.size
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def each_connection(&callback)
|
69
|
+
return self unless block_given?
|
70
|
+
raise Errors::IOError, 'Not connected' unless connected?
|
71
|
+
@lock.synchronize do
|
72
|
+
@connections.each(&callback)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
alias each each_connection
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,372 @@
|
|
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 Connector
|
23
|
+
include MonitorMixin
|
24
|
+
|
25
|
+
def initialize(logger,
|
26
|
+
io_reactor,
|
27
|
+
cluster_registry,
|
28
|
+
connection_options,
|
29
|
+
execution_options)
|
30
|
+
@logger = logger
|
31
|
+
@reactor = io_reactor
|
32
|
+
@registry = cluster_registry
|
33
|
+
@connection_options = connection_options
|
34
|
+
@execution_options = execution_options
|
35
|
+
@connections = ::Hash.new
|
36
|
+
@open_connections = ::Hash.new
|
37
|
+
|
38
|
+
mon_initialize
|
39
|
+
end
|
40
|
+
|
41
|
+
def connect(host)
|
42
|
+
synchronize do
|
43
|
+
open_connections = @open_connections[host]
|
44
|
+
if open_connections
|
45
|
+
connection = open_connections.shift
|
46
|
+
@open_connections.delete(host) if open_connections.empty?
|
47
|
+
return Ione::Future.resolved(connection)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
f = do_connect(host)
|
52
|
+
|
53
|
+
f.on_failure do |error|
|
54
|
+
connection_error(host, error)
|
55
|
+
end
|
56
|
+
|
57
|
+
f.on_value do |connection|
|
58
|
+
connection.on_closed do |cause|
|
59
|
+
disconnected(host, cause)
|
60
|
+
end
|
61
|
+
|
62
|
+
connected(host)
|
63
|
+
end
|
64
|
+
|
65
|
+
f
|
66
|
+
end
|
67
|
+
|
68
|
+
def refresh_status(host)
|
69
|
+
if synchronize { @connections[host] }
|
70
|
+
@registry.host_up(host.ip)
|
71
|
+
|
72
|
+
return Future.resolved
|
73
|
+
end
|
74
|
+
|
75
|
+
@logger.debug("Checking if host #{host.ip} is up")
|
76
|
+
f = do_connect(host)
|
77
|
+
|
78
|
+
f.on_failure do |error|
|
79
|
+
connection_error(host, error)
|
80
|
+
end
|
81
|
+
|
82
|
+
f.on_value do |connection|
|
83
|
+
connection.on_closed do |cause|
|
84
|
+
disconnected(host, cause)
|
85
|
+
end
|
86
|
+
|
87
|
+
synchronize do
|
88
|
+
@open_connections[host] ||= []
|
89
|
+
@open_connections[host] << connection
|
90
|
+
end
|
91
|
+
|
92
|
+
timer = @reactor.schedule_timer(UNCLAIMED_TIMEOUT)
|
93
|
+
timer.on_value do
|
94
|
+
close = false
|
95
|
+
|
96
|
+
synchronize do
|
97
|
+
open_connections = @open_connections[host]
|
98
|
+
if open_connections
|
99
|
+
close = !open_connections.delete(connection).nil?
|
100
|
+
@open_connections.delete(host) if open_connections.empty?
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
connection.close if close
|
105
|
+
end
|
106
|
+
|
107
|
+
connected(host)
|
108
|
+
end
|
109
|
+
|
110
|
+
f
|
111
|
+
end
|
112
|
+
|
113
|
+
private
|
114
|
+
|
115
|
+
NO_CONNECTIONS = Ione::Future.resolved([])
|
116
|
+
UNCLAIMED_TIMEOUT = 5 # close unclaimed connections in five seconds
|
117
|
+
|
118
|
+
def do_connect(host)
|
119
|
+
@reactor.connect(host.ip.to_s,
|
120
|
+
@connection_options.port,
|
121
|
+
timeout: @connection_options.connect_timeout,
|
122
|
+
ssl: @connection_options.ssl) do |connection|
|
123
|
+
raise Errors::ClientError, 'Not connected, reactor stopped' unless connection
|
124
|
+
|
125
|
+
connection.to_io.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY,
|
126
|
+
@connection_options.nodelay? ? 1 : 0)
|
127
|
+
|
128
|
+
Protocol::CqlProtocolHandler.new(connection,
|
129
|
+
@reactor,
|
130
|
+
@connection_options.protocol_version,
|
131
|
+
@connection_options.compressor,
|
132
|
+
@connection_options.heartbeat_interval,
|
133
|
+
@connection_options.idle_timeout,
|
134
|
+
@connection_options.requests_per_connection,
|
135
|
+
@connection_options.custom_type_handlers)
|
136
|
+
end.flat_map do |connection|
|
137
|
+
# connection is a CqlProtocolHandler
|
138
|
+
f = request_options(connection)
|
139
|
+
f = f.flat_map do |options|
|
140
|
+
compression = @connection_options.compression
|
141
|
+
supported_algorithms = options['COMPRESSION']
|
142
|
+
|
143
|
+
if compression && !supported_algorithms.include?(compression)
|
144
|
+
@logger.warn("Compression with #{compression.inspect} is not supported " \
|
145
|
+
"by host at #{host.ip}, supported algorithms are " \
|
146
|
+
"#{supported_algorithms.inspect}")
|
147
|
+
compression = nil
|
148
|
+
end
|
149
|
+
|
150
|
+
supported_cql_versions = options['CQL_VERSION']
|
151
|
+
cql_version = (supported_cql_versions && !supported_cql_versions.empty?) ?
|
152
|
+
supported_cql_versions.first :
|
153
|
+
'3.1.0'
|
154
|
+
|
155
|
+
startup_connection(host, connection, cql_version, compression)
|
156
|
+
end
|
157
|
+
f.fallback do |error|
|
158
|
+
case error
|
159
|
+
when Errors::ProtocolError
|
160
|
+
synchronize do
|
161
|
+
current_version = connection.protocol_version
|
162
|
+
if current_version > 1 && @connection_options.protocol_negotiable?
|
163
|
+
@logger.info("Host #{host.ip} doesn't support protocol version " \
|
164
|
+
"#{current_version}, downgrading")
|
165
|
+
|
166
|
+
# This is tricky. We want to try with the next lower protocol version.
|
167
|
+
# However, the connection_options used for all connections may have
|
168
|
+
# already been updated due to other node connection failures. So,
|
169
|
+
# it may already have a lower protocol-version than our current-1. We
|
170
|
+
# don't want to accidentally raise it, so we update it to the min
|
171
|
+
# of itself and current-1.
|
172
|
+
@connection_options.protocol_version =
|
173
|
+
[@connection_options.protocol_version, current_version - 1].min
|
174
|
+
do_connect(host)
|
175
|
+
else
|
176
|
+
Ione::Future.failed(error)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
when Errors::TimeoutError
|
180
|
+
future = Ione::CompletableFuture.new
|
181
|
+
connection.close(error).on_complete do |_|
|
182
|
+
future.fail(error)
|
183
|
+
end
|
184
|
+
future
|
185
|
+
else
|
186
|
+
Ione::Future.failed(error)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end.fallback do |error|
|
190
|
+
case error
|
191
|
+
when Error
|
192
|
+
Ione::Future.failed(error)
|
193
|
+
else
|
194
|
+
e = Errors::IOError.new(error.message)
|
195
|
+
e.set_backtrace(error.backtrace)
|
196
|
+
Ione::Future.failed(e)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def startup_connection(host, connection, cql_version, compression)
|
202
|
+
connection.send_request(Protocol::StartupRequest.new(cql_version, compression),
|
203
|
+
@execution_options.timeout).flat_map do |r|
|
204
|
+
case r
|
205
|
+
when Protocol::AuthenticateResponse
|
206
|
+
if @connection_options.protocol_version == 1
|
207
|
+
credentials = @connection_options.credentials
|
208
|
+
if credentials
|
209
|
+
send_credentials(connection, credentials)
|
210
|
+
else
|
211
|
+
Ione::Future.failed(cannot_authenticate_error)
|
212
|
+
end
|
213
|
+
else
|
214
|
+
authenticator = @connection_options.create_authenticator(r.authentication_class, host)
|
215
|
+
if authenticator
|
216
|
+
challenge_response_cycle(connection, authenticator, authenticator.initial_response)
|
217
|
+
else
|
218
|
+
Ione::Future.failed(cannot_authenticate_error)
|
219
|
+
end
|
220
|
+
end
|
221
|
+
when Protocol::ReadyResponse
|
222
|
+
::Ione::Future.resolved(connection)
|
223
|
+
when Protocol::ErrorResponse
|
224
|
+
::Ione::Future.failed(
|
225
|
+
r.to_error(nil, VOID_STATEMENT, VOID_OPTIONS, EMPTY_LIST, :quorum, 0)
|
226
|
+
)
|
227
|
+
else
|
228
|
+
::Ione::Future.failed(
|
229
|
+
Errors::InternalError.new("Unexpected response #{r.inspect}")
|
230
|
+
)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
def cannot_authenticate_error
|
236
|
+
Errors::AuthenticationError.new(
|
237
|
+
'Server requested authentication, but client was not configured to ' \
|
238
|
+
'authenticate',
|
239
|
+
nil,
|
240
|
+
nil,
|
241
|
+
nil,
|
242
|
+
VOID_STATEMENT,
|
243
|
+
VOID_OPTIONS,
|
244
|
+
EMPTY_LIST,
|
245
|
+
:quorum,
|
246
|
+
0
|
247
|
+
)
|
248
|
+
end
|
249
|
+
|
250
|
+
def request_options(connection)
|
251
|
+
connection.send_request(Protocol::OptionsRequest.new,
|
252
|
+
@execution_options.timeout).map do |r|
|
253
|
+
case r
|
254
|
+
when Protocol::SupportedResponse
|
255
|
+
r.options
|
256
|
+
when Protocol::ErrorResponse
|
257
|
+
raise r.to_error(nil, VOID_STATEMENT, VOID_OPTIONS, EMPTY_LIST, :quorum, 0)
|
258
|
+
else
|
259
|
+
raise Errors::InternalError, "Unexpected response #{r.inspect}"
|
260
|
+
end
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
def send_credentials(connection, credentials)
|
265
|
+
connection.send_request(Protocol::CredentialsRequest.new(credentials),
|
266
|
+
@execution_options.timeout).map do |r|
|
267
|
+
case r
|
268
|
+
when Protocol::ReadyResponse
|
269
|
+
connection
|
270
|
+
when Protocol::ErrorResponse
|
271
|
+
raise r.to_error(nil, VOID_STATEMENT, VOID_OPTIONS, EMPTY_LIST, :quorum, 0)
|
272
|
+
else
|
273
|
+
raise Errors::InternalError, "Unexpected response #{r.inspect}"
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
def challenge_response_cycle(connection, authenticator, token)
|
279
|
+
connection.send_request(Protocol::AuthResponseRequest.new(token),
|
280
|
+
@execution_options.timeout).flat_map do |r|
|
281
|
+
case r
|
282
|
+
when Protocol::AuthChallengeResponse
|
283
|
+
token = authenticator.challenge_response(r.token)
|
284
|
+
challenge_response_cycle(connection, authenticator, token)
|
285
|
+
when Protocol::AuthSuccessResponse
|
286
|
+
begin
|
287
|
+
authenticator.authentication_successful(r.token)
|
288
|
+
rescue
|
289
|
+
nil
|
290
|
+
end
|
291
|
+
::Ione::Future.resolved(connection)
|
292
|
+
when Protocol::ErrorResponse
|
293
|
+
::Ione::Future.failed(
|
294
|
+
r.to_error(nil, VOID_STATEMENT, VOID_OPTIONS, EMPTY_LIST, :quorum, 0)
|
295
|
+
)
|
296
|
+
else
|
297
|
+
::Ione::Future.failed(
|
298
|
+
Errors::InternalError.new("Unexpected response #{r.inspect}")
|
299
|
+
)
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
def connected(host)
|
305
|
+
notify = false
|
306
|
+
|
307
|
+
synchronize do
|
308
|
+
connections = @connections[host]
|
309
|
+
|
310
|
+
if connections
|
311
|
+
@connections[host] = connections + 1
|
312
|
+
else
|
313
|
+
notify = true
|
314
|
+
|
315
|
+
@connections[host] = 1
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
@registry.host_up(host.ip) if notify
|
320
|
+
|
321
|
+
self
|
322
|
+
end
|
323
|
+
|
324
|
+
def disconnected(host, error)
|
325
|
+
notify = false
|
326
|
+
|
327
|
+
synchronize do
|
328
|
+
connections = @connections[host]
|
329
|
+
|
330
|
+
return self unless connections
|
331
|
+
|
332
|
+
connections -= 1
|
333
|
+
|
334
|
+
if connections == 0
|
335
|
+
notify = !error.nil?
|
336
|
+
@connections.delete(host)
|
337
|
+
else
|
338
|
+
@connections[host] = connections
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
@logger.debug("Host #{host.ip} closed connection (#{error.class.name}: " \
|
343
|
+
"#{error.message})") if error
|
344
|
+
|
345
|
+
if notify
|
346
|
+
@logger.warn("Host #{host.ip} closed all connections")
|
347
|
+
@registry.host_down(host.ip)
|
348
|
+
end
|
349
|
+
|
350
|
+
self
|
351
|
+
end
|
352
|
+
|
353
|
+
def connection_error(host, error)
|
354
|
+
notify = false
|
355
|
+
|
356
|
+
synchronize do
|
357
|
+
notify = !error.nil? && !@connections.key?(host)
|
358
|
+
end
|
359
|
+
|
360
|
+
@logger.debug("Host #{host.ip} refused connection (#{error.class.name}: " \
|
361
|
+
"#{error.message})")
|
362
|
+
|
363
|
+
if notify
|
364
|
+
@logger.warn("Host #{host.ip} refused all connections")
|
365
|
+
@registry.host_down(host.ip)
|
366
|
+
end
|
367
|
+
|
368
|
+
self
|
369
|
+
end
|
370
|
+
end
|
371
|
+
end
|
372
|
+
end
|