cassandra-driver 1.0.0.beta.3 → 1.0.0.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +13 -5
- data/README.md +8 -6
- data/lib/cassandra.rb +99 -13
- 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/auth.rb +1 -1
- data/lib/cassandra/auth/providers/password.rb +1 -1
- data/lib/cassandra/client.rb +2 -2
- data/lib/cassandra/client/batch.rb +3 -3
- data/lib/cassandra/client/client.rb +12 -12
- data/lib/cassandra/client/connection_manager.rb +2 -2
- data/lib/cassandra/client/connector.rb +6 -10
- data/lib/cassandra/client/prepared_statement.rb +4 -4
- data/lib/cassandra/client/request_runner.rb +1 -2
- data/lib/cassandra/cluster.rb +15 -5
- data/lib/cassandra/cluster/client.rb +158 -96
- data/lib/cassandra/cluster/connector.rb +42 -27
- data/lib/cassandra/cluster/control_connection.rb +384 -132
- data/lib/cassandra/cluster/options.rb +5 -2
- data/lib/cassandra/cluster/registry.rb +19 -9
- data/lib/cassandra/compression.rb +1 -1
- data/lib/cassandra/compression/compressors/lz4.rb +1 -1
- data/lib/cassandra/compression/compressors/snappy.rb +1 -1
- data/lib/cassandra/driver.rb +28 -20
- data/lib/cassandra/errors.rb +325 -35
- data/lib/cassandra/future.rb +3 -3
- data/lib/cassandra/load_balancing/policies/dc_aware_round_robin.rb +7 -3
- data/lib/cassandra/load_balancing/policies/token_aware.rb +1 -1
- data/lib/cassandra/protocol.rb +0 -16
- data/lib/cassandra/protocol/cql_byte_buffer.rb +18 -18
- data/lib/cassandra/protocol/cql_protocol_handler.rb +74 -8
- data/lib/cassandra/protocol/frame_decoder.rb +2 -2
- data/lib/cassandra/protocol/frame_encoder.rb +1 -1
- data/lib/cassandra/protocol/response.rb +1 -1
- data/lib/cassandra/protocol/responses/detailed_error_response.rb +16 -1
- data/lib/cassandra/protocol/responses/error_response.rb +17 -0
- data/lib/cassandra/protocol/responses/event_response.rb +1 -1
- data/lib/cassandra/protocol/responses/raw_rows_result_response.rb +1 -1
- data/lib/cassandra/protocol/responses/result_response.rb +1 -1
- data/lib/cassandra/protocol/responses/rows_result_response.rb +1 -1
- data/lib/cassandra/protocol/type_converter.rb +4 -3
- data/lib/cassandra/reconnection.rb +1 -1
- data/lib/cassandra/retry.rb +3 -5
- data/lib/cassandra/session.rb +11 -5
- data/lib/cassandra/table.rb +1 -1
- data/lib/cassandra/time_uuid.rb +21 -83
- data/lib/cassandra/util.rb +1 -1
- data/lib/cassandra/uuid.rb +6 -4
- data/lib/cassandra/uuid/generator.rb +207 -0
- data/lib/cassandra/version.rb +1 -1
- metadata +24 -19
@@ -22,10 +22,11 @@ module Cassandra
|
|
22
22
|
class Options
|
23
23
|
attr_reader :credentials, :auth_provider, :compressor, :port,
|
24
24
|
:connect_timeout, :ssl, :connections_per_local_node,
|
25
|
-
:connections_per_remote_node
|
25
|
+
:connections_per_remote_node, :heartbeat_interval,
|
26
|
+
:idle_timeout
|
26
27
|
attr_accessor :protocol_version
|
27
28
|
|
28
|
-
def initialize(protocol_version, credentials, auth_provider, compressor, port, connect_timeout, ssl, connections_per_local_node, connections_per_remote_node)
|
29
|
+
def initialize(protocol_version, credentials, auth_provider, compressor, port, connect_timeout, ssl, connections_per_local_node, connections_per_remote_node, heartbeat_interval, idle_timeout)
|
29
30
|
@protocol_version = protocol_version
|
30
31
|
@credentials = credentials
|
31
32
|
@auth_provider = auth_provider
|
@@ -33,6 +34,8 @@ module Cassandra
|
|
33
34
|
@port = port
|
34
35
|
@connect_timeout = connect_timeout
|
35
36
|
@ssl = ssl
|
37
|
+
@heartbeat_interval = heartbeat_interval
|
38
|
+
@idle_timeout = idle_timeout
|
36
39
|
|
37
40
|
@connections_per_local_node = connections_per_local_node
|
38
41
|
@connections_per_remote_node = connections_per_remote_node
|
@@ -22,24 +22,30 @@ module Cassandra
|
|
22
22
|
class Registry
|
23
23
|
include MonitorMixin
|
24
24
|
|
25
|
-
LISTENER_METHODS = [:host_found, :host_lost, :host_up, :host_down].freeze
|
26
|
-
|
27
25
|
def initialize(logger)
|
28
26
|
@logger = logger
|
29
27
|
@hosts = ::Hash.new
|
30
|
-
@listeners = ::
|
28
|
+
@listeners = ::Array.new
|
31
29
|
|
32
30
|
mon_initialize
|
33
31
|
end
|
34
32
|
|
35
33
|
def add_listener(listener)
|
36
|
-
synchronize
|
34
|
+
synchronize do
|
35
|
+
listeners = @listeners.dup
|
36
|
+
listeners.push(listener)
|
37
|
+
@listeners = listeners
|
38
|
+
end
|
37
39
|
|
38
40
|
self
|
39
41
|
end
|
40
42
|
|
41
43
|
def remove_listener(listener)
|
42
|
-
synchronize
|
44
|
+
synchronize do
|
45
|
+
listeners = @listeners.dup
|
46
|
+
listeners.delete(listener)
|
47
|
+
@listeners = listeners
|
48
|
+
end
|
43
49
|
|
44
50
|
self
|
45
51
|
end
|
@@ -72,8 +78,12 @@ module Cassandra
|
|
72
78
|
host.rack == data['rack'] &&
|
73
79
|
host.datacenter == data['data_center']
|
74
80
|
|
75
|
-
return self
|
81
|
+
return self if host.up?
|
82
|
+
|
83
|
+
host = toggle_up(host)
|
76
84
|
else
|
85
|
+
@logger.debug("Host #{host.ip} metadata has been updated, it will be considered lost and found")
|
86
|
+
|
77
87
|
notify_lost(host)
|
78
88
|
|
79
89
|
host = create_host(address, data)
|
@@ -164,7 +174,7 @@ module Cassandra
|
|
164
174
|
def toggle_down(host)
|
165
175
|
host = Host.new(host.ip, host.id, host.rack, host.datacenter, host.release_version, host.tokens, :down)
|
166
176
|
@logger.debug("Host #{host.ip} is down")
|
167
|
-
@listeners.
|
177
|
+
@listeners.reverse_each do |listener|
|
168
178
|
listener.host_down(host) rescue nil
|
169
179
|
end
|
170
180
|
host
|
@@ -174,13 +184,13 @@ module Cassandra
|
|
174
184
|
if host.up?
|
175
185
|
@logger.debug("Host #{host.ip} is down and lost")
|
176
186
|
host = Host.new(host.ip, host.id, host.rack, host.datacenter, host.release_version, host.tokens, :down)
|
177
|
-
@listeners.
|
187
|
+
@listeners.reverse_each do |listener|
|
178
188
|
listener.host_down(host) rescue nil
|
179
189
|
listener.host_lost(host) rescue nil
|
180
190
|
end
|
181
191
|
else
|
182
192
|
@logger.debug("Host #{host.ip} is lost")
|
183
|
-
@listeners.
|
193
|
+
@listeners.reverse_each do |listener|
|
184
194
|
listener.host_lost(host) rescue nil
|
185
195
|
end
|
186
196
|
end
|
@@ -18,7 +18,7 @@
|
|
18
18
|
|
19
19
|
module Cassandra
|
20
20
|
module Compression
|
21
|
-
# @abstract Compressors given to {Cassandra.
|
21
|
+
# @abstract Compressors given to {Cassandra.cluster} as the `:compressor`
|
22
22
|
# option don't need to be subclasses of this class, but need to implement
|
23
23
|
# the same methods. This class exists only for documentation purposes.
|
24
24
|
class Compressor
|
@@ -31,7 +31,7 @@ module Cassandra
|
|
31
31
|
# [lz4-ruby](http://rubygems.org/gems/lz4-ruby) gem (v0.3.2 or later
|
32
32
|
# required).
|
33
33
|
# @note No need to instantiate this class manually, use `compression:
|
34
|
-
# :lz4` option when calling {Cassandra.
|
34
|
+
# :lz4` option when calling {Cassandra.cluster} and one will be created
|
35
35
|
# automatically for you.
|
36
36
|
class Lz4 < Compressor
|
37
37
|
# @return [String] `'lz4'`
|
@@ -31,7 +31,7 @@ module Cassandra
|
|
31
31
|
# [snappy](http://rubygems.org/gems/snappy) gem (v0.0.10 or later for
|
32
32
|
# JRuby support).
|
33
33
|
# @note No need to instantiate this class manually, use `compression:
|
34
|
-
# :snappy` option when calling {Cassandra.
|
34
|
+
# :snappy` option when calling {Cassandra.cluster} and one will be
|
35
35
|
# created automatically for you.
|
36
36
|
class Snappy < Compressor
|
37
37
|
# @return [String] `'snappy'`
|
data/lib/cassandra/driver.rb
CHANGED
@@ -24,7 +24,7 @@ module Cassandra
|
|
24
24
|
define_method(:"#{name}=") { |object| @instances[name] = object }
|
25
25
|
end
|
26
26
|
|
27
|
-
let(:io_reactor) { Io::IoReactor.new }
|
27
|
+
let(:io_reactor) { Ione::Io::IoReactor.new }
|
28
28
|
let(:cluster_registry) { Cluster::Registry.new(logger) }
|
29
29
|
let(:cluster_schema) { Cluster::Schema.new(schema_type_parser) }
|
30
30
|
let(:cluster_metadata) { Cluster::Metadata.new(
|
@@ -56,34 +56,40 @@ module Cassandra
|
|
56
56
|
|
57
57
|
let(:connector) { Cluster::Connector.new(logger, io_reactor, cluster_registry, connection_options) }
|
58
58
|
|
59
|
-
let(:control_connection) { Cluster::ControlConnection.new(logger, io_reactor, cluster_registry, cluster_schema, cluster_metadata, load_balancing_policy, reconnection_policy, connector) }
|
59
|
+
let(:control_connection) { Cluster::ControlConnection.new(logger, io_reactor, cluster_registry, cluster_schema, cluster_metadata, load_balancing_policy, reconnection_policy, address_resolution_policy, connector) }
|
60
60
|
|
61
|
-
let(:cluster) { Cluster.new(logger, io_reactor, control_connection, cluster_registry, cluster_schema, cluster_metadata, execution_options, connection_options, load_balancing_policy, reconnection_policy, retry_policy, connector, futures_factory) }
|
61
|
+
let(:cluster) { Cluster.new(logger, io_reactor, control_connection, cluster_registry, cluster_schema, cluster_metadata, execution_options, connection_options, load_balancing_policy, reconnection_policy, retry_policy, address_resolution_policy, connector, futures_factory) }
|
62
62
|
|
63
63
|
let(:execution_options) do
|
64
64
|
Execution::Options.new({
|
65
65
|
:consistency => consistency,
|
66
66
|
:trace => trace,
|
67
|
-
:page_size => page_size
|
67
|
+
:page_size => page_size,
|
68
|
+
:timeout => timeout
|
68
69
|
})
|
69
70
|
end
|
70
71
|
|
71
|
-
let(:connection_options) { Cluster::Options.new(protocol_version, credentials, auth_provider, compressor, port, connect_timeout, ssl, connections_per_local_node, connections_per_remote_node) }
|
72
|
-
|
73
|
-
let(:port)
|
74
|
-
let(:protocol_version)
|
75
|
-
let(:connect_timeout)
|
76
|
-
let(:ssl)
|
77
|
-
let(:logger)
|
78
|
-
let(:compressor)
|
79
|
-
let(:credentials)
|
80
|
-
let(:auth_provider)
|
81
|
-
let(:
|
82
|
-
let(:
|
83
|
-
let(:
|
84
|
-
let(:
|
85
|
-
let(:
|
86
|
-
let(:
|
72
|
+
let(:connection_options) { Cluster::Options.new(protocol_version, credentials, auth_provider, compressor, port, connect_timeout, ssl, connections_per_local_node, connections_per_remote_node, heartbeat_interval, idle_timeout) }
|
73
|
+
|
74
|
+
let(:port) { 9042 }
|
75
|
+
let(:protocol_version) { 2 }
|
76
|
+
let(:connect_timeout) { 10 }
|
77
|
+
let(:ssl) { false }
|
78
|
+
let(:logger) { Client::NullLogger.new }
|
79
|
+
let(:compressor) { nil }
|
80
|
+
let(:credentials) { nil }
|
81
|
+
let(:auth_provider) { nil }
|
82
|
+
let(:datacenter) { nil }
|
83
|
+
let(:load_balancing_policy) { LoadBalancing::Policies::TokenAware.new(LoadBalancing::Policies::DCAwareRoundRobin.new(datacenter, 0)) }
|
84
|
+
let(:reconnection_policy) { Reconnection::Policies::Exponential.new(0.5, 30, 2) }
|
85
|
+
let(:retry_policy) { Retry::Policies::Default.new }
|
86
|
+
let(:address_resolution_policy) { AddressResolution::Policies::None.new }
|
87
|
+
let(:consistency) { :one }
|
88
|
+
let(:trace) { false }
|
89
|
+
let(:page_size) { nil }
|
90
|
+
let(:heartbeat_interval) { 30 }
|
91
|
+
let(:idle_timeout) { 60 }
|
92
|
+
let(:timeout) { 10 }
|
87
93
|
|
88
94
|
let(:connections_per_local_node) { 2 }
|
89
95
|
let(:connections_per_remote_node) { 1 }
|
@@ -103,8 +109,10 @@ module Cassandra
|
|
103
109
|
cluster.register(listener)
|
104
110
|
end
|
105
111
|
|
112
|
+
logger.debug('Populating policies and listeners with initial endpoints')
|
106
113
|
addresses.each {|address| cluster_registry.host_found(address)}
|
107
114
|
|
115
|
+
logger.info('Establishing control connection')
|
108
116
|
control_connection.connect_async.map(cluster)
|
109
117
|
end
|
110
118
|
end
|
data/lib/cassandra/errors.rb
CHANGED
@@ -17,63 +17,353 @@
|
|
17
17
|
#++
|
18
18
|
|
19
19
|
module Cassandra
|
20
|
-
#
|
20
|
+
# Included in all Errors raised by the driver to allow rescuing from any
|
21
|
+
# driver-specific error.
|
22
|
+
# @example Catching all driver errors
|
23
|
+
# begin
|
24
|
+
# cluster = Cassandra.cluster
|
25
|
+
# session = cluster.connect
|
26
|
+
# rescue Cassandra::Error => e
|
27
|
+
# puts "#{e.class.name}: #{e.message}"
|
28
|
+
# end
|
21
29
|
# @see Cassandra::Errors
|
22
|
-
|
30
|
+
module Error
|
23
31
|
end
|
24
32
|
|
25
33
|
module Errors
|
26
|
-
#
|
27
|
-
#
|
28
|
-
|
29
|
-
|
30
|
-
#
|
31
|
-
#
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
34
|
+
# Mixed into any host-specific errors. Requests resulting in these errors
|
35
|
+
# are attempted on other hosts. Once all hosts failed with this type of
|
36
|
+
# error, a {Cassandra::Errors::NoHostsAvailable} error is raised with
|
37
|
+
# details of failures.
|
38
|
+
#
|
39
|
+
# @see Errors::NoHostsAvailable
|
40
|
+
module HostError
|
41
|
+
end
|
42
|
+
|
43
|
+
# Raised when something unexpected happened. This indicates a server-side
|
44
|
+
# bug.
|
45
|
+
#
|
46
|
+
# @see https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v1.spec#L554-L555 Description of Server Error in Apache Cassandra native protocol spec v1
|
47
|
+
class ServerError < ::StandardError
|
48
|
+
include Error, HostError
|
49
|
+
end
|
50
|
+
|
51
|
+
# Mixed into all internal driver errors.
|
52
|
+
module InternalError
|
53
|
+
include Error, HostError
|
54
|
+
end
|
55
|
+
|
56
|
+
# Raised when data decoding fails.
|
57
|
+
class DecodingError < ::RuntimeError
|
58
|
+
include InternalError
|
59
|
+
end
|
60
|
+
|
61
|
+
# Raised when data encoding fails.
|
62
|
+
class EncodingError < ::RuntimeError
|
63
|
+
include InternalError
|
64
|
+
end
|
65
|
+
|
66
|
+
# Raised when a connection level error occured.
|
67
|
+
class IOError < ::IOError
|
68
|
+
include InternalError
|
69
|
+
end
|
70
|
+
|
71
|
+
# Raised when a timeout has occured.
|
72
|
+
class TimeoutError < ::Timeout::Error
|
73
|
+
include InternalError
|
74
|
+
end
|
75
|
+
|
76
|
+
# Mixed into all request execution errors.
|
77
|
+
module ExecutionError
|
78
|
+
include Error
|
79
|
+
|
80
|
+
# @return [Cassandra::Statement] statement that triggered the error.
|
81
|
+
attr_reader :statement
|
41
82
|
|
42
83
|
# @private
|
43
|
-
def initialize(
|
84
|
+
def initialize(message, statement)
|
44
85
|
super(message)
|
45
|
-
|
46
|
-
@
|
47
|
-
@details = details
|
86
|
+
|
87
|
+
@statement = statement
|
48
88
|
end
|
49
89
|
end
|
50
90
|
|
51
|
-
#
|
52
|
-
|
53
|
-
|
54
|
-
|
91
|
+
# Raised when coordinator determines that a request cannot be executed
|
92
|
+
# because there are not enough replicas. In this scenario, the request is
|
93
|
+
# not sent to the nodes at all.
|
94
|
+
#
|
95
|
+
# @note This error can be handled by a {Cassandra::Retry::Policy} to
|
96
|
+
# determine the desired outcome.
|
97
|
+
#
|
98
|
+
# @see https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v1.spec#L562-L572 Description of Unavailable Error in Apache Cassandra native protocol spec v1
|
99
|
+
class UnavailableError < ::StandardError
|
100
|
+
include ExecutionError
|
101
|
+
# Consistency level that triggered the error.
|
102
|
+
#
|
103
|
+
# @return [Symbol] the original consistency level for the request, one of
|
104
|
+
# {Cassandra::CONSISTENCIES}
|
105
|
+
attr_reader :consistency
|
106
|
+
|
107
|
+
# @return [Integer] the number of replicas required to achieve requested
|
108
|
+
# consistency level
|
109
|
+
attr_reader :required
|
110
|
+
|
111
|
+
# @return [Integer] the number of replicas available for the request
|
112
|
+
attr_reader :alive
|
55
113
|
|
56
114
|
# @private
|
57
|
-
def initialize(
|
58
|
-
super(
|
115
|
+
def initialize(message, statement, consistency, required, alive)
|
116
|
+
super(message, statement)
|
59
117
|
|
60
|
-
@
|
118
|
+
@consistency = consistency
|
119
|
+
@required = required
|
120
|
+
@alive = alive
|
61
121
|
end
|
62
122
|
end
|
63
123
|
|
64
|
-
#
|
124
|
+
# Raised when the request cannot be processed because the coordinator node
|
125
|
+
# is overloaded
|
126
|
+
#
|
127
|
+
# @see https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v1.spec#L573-L574 Description of Overloaded Error in Apache Cassandra native protocol spec v1
|
128
|
+
class OverloadedError < ::StandardError
|
129
|
+
include ExecutionError, HostError
|
130
|
+
end
|
131
|
+
|
132
|
+
# Raise when the request was a read request but the coordinator node is
|
133
|
+
# bootstrapping
|
134
|
+
#
|
135
|
+
# @see https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v1.spec#L575-L576 Description of Is Bootstrapping Error in Apache Cassandra native protocol spec v1
|
136
|
+
class IsBootstrappingError < ::StandardError
|
137
|
+
include ExecutionError, HostError
|
138
|
+
end
|
139
|
+
|
140
|
+
# Raised when truncation failed.
|
141
|
+
#
|
142
|
+
# @see https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v1.spec#L577 Description of Truncate Error in Apache Cassandra native protocol spec v1
|
143
|
+
class TruncateError < ::StandardError
|
144
|
+
include ExecutionError
|
145
|
+
end
|
146
|
+
|
147
|
+
# Raised when a write request timed out.
|
148
|
+
#
|
149
|
+
# @see https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v1.spec#L578-L603 Description of Write Timeout Error in Apache Cassandra native protocol spec v1
|
150
|
+
class WriteTimeoutError < ::StandardError
|
151
|
+
include ExecutionError
|
152
|
+
|
153
|
+
# @return [Symbol] the type of write request that timed out, one of
|
154
|
+
# {Cassandra::WRITE_TYPES}
|
155
|
+
attr_reader :type
|
156
|
+
# @return [Symbol] the original consistency level for the request, one of
|
157
|
+
# {Cassandra::CONSISTENCIES}
|
158
|
+
attr_reader :consistency
|
159
|
+
# @return [Integer] the number of acks required to achieve requested
|
160
|
+
# consistency level
|
161
|
+
attr_reader :required
|
162
|
+
# @return [Integer] the number of acks received by the time the query
|
163
|
+
# timed out
|
164
|
+
attr_reader :received
|
165
|
+
|
166
|
+
# @private
|
167
|
+
def initialize(message, statement, type, consistency, required, received)
|
168
|
+
super(message, statement)
|
169
|
+
|
170
|
+
@type = type
|
171
|
+
@consistency = consistency
|
172
|
+
@required = required
|
173
|
+
@received = received
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
# Raised when a read request timed out.
|
178
|
+
#
|
179
|
+
# @see https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v1.spec#L604-L622 Description of Read Timeout Error in Apache Cassandra native protocol spec v1
|
180
|
+
class ReadTimeoutError < ::StandardError
|
181
|
+
include ExecutionError
|
182
|
+
|
183
|
+
# @return [Boolean] whether actual data (as opposed to data checksum) was
|
184
|
+
# present in the received responses.
|
185
|
+
attr_reader :retrieved
|
186
|
+
# @return [Symbol] the original consistency level for the request, one of
|
187
|
+
# {Cassandra::CONSISTENCIES}
|
188
|
+
attr_reader :consistency
|
189
|
+
# @return [Integer] the number of responses required to achieve requested
|
190
|
+
# consistency level
|
191
|
+
attr_reader :required
|
192
|
+
# @return [Integer] the number of responses received by the time the
|
193
|
+
# query timed out
|
194
|
+
attr_reader :received
|
195
|
+
|
196
|
+
# @private
|
197
|
+
def initialize(message, statement, retrieved, consistency, required, received)
|
198
|
+
super(message, statement)
|
199
|
+
|
200
|
+
@retrieved = retrieved
|
201
|
+
@consistency = consistency
|
202
|
+
@required = required
|
203
|
+
@received = received
|
204
|
+
end
|
205
|
+
|
206
|
+
def retrieved?
|
207
|
+
@retrieved
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
# Client error represents bad driver state or mis-configuration
|
212
|
+
class ClientError < ::StandardError
|
213
|
+
include Error
|
214
|
+
end
|
215
|
+
|
216
|
+
# Raised when some client message triggered a protocol violation (for
|
217
|
+
# instance a QUERY message is sent before a STARTUP one has been sent)
|
65
218
|
#
|
66
|
-
# @see Cassandra
|
67
|
-
class
|
219
|
+
# @see https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v1.spec#L556-L558 Description of Protocol Error in Apache Cassandra native protocol spec v1
|
220
|
+
class ProtocolError < ClientError
|
68
221
|
end
|
69
222
|
|
70
223
|
# Raised when cannot authenticate to Cassandra
|
224
|
+
#
|
225
|
+
# @see https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v1.spec#L559-L561 Description of Bad Credentials Error in Apache Cassandra native protocol spec v1
|
71
226
|
class AuthenticationError < ClientError
|
72
227
|
end
|
73
228
|
|
74
|
-
#
|
75
|
-
|
76
|
-
|
77
|
-
|
229
|
+
# Mixed into all request validation errors.
|
230
|
+
module ValidationError
|
231
|
+
include Error
|
232
|
+
|
233
|
+
# @return [Cassandra::Statement] statement that triggered the error.
|
234
|
+
attr_reader :statement
|
235
|
+
|
236
|
+
# @private
|
237
|
+
def initialize(message, statement)
|
238
|
+
super(message)
|
239
|
+
|
240
|
+
@statement = statement
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
# Raised when a prepared statement tries to be executed and the provided
|
245
|
+
# prepared statement ID is not known by this host
|
246
|
+
#
|
247
|
+
# @note Seeing this error can be considered a Ruby Driver bug as it should
|
248
|
+
# handle automatic re-preparing internally.
|
249
|
+
#
|
250
|
+
# @see https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v1.spec#L638-L641 Description of Unprepared Error in Apache Cassandra native protocol spec v1
|
251
|
+
class UnpreparedError < ::StandardError
|
252
|
+
include ValidationError
|
253
|
+
# @return [String] prepared statement id that triggered the error
|
254
|
+
attr_reader :id
|
255
|
+
|
256
|
+
# @private
|
257
|
+
def initialize(message, statement, id)
|
258
|
+
super(message, statement)
|
259
|
+
|
260
|
+
@id = id
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
# Raised when the submitted query has a syntax error.
|
265
|
+
#
|
266
|
+
# @see https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v1.spec#L623 Description of Syntax Error in Apache Cassandra native protocol spec v1
|
267
|
+
class SyntaxError < ::StandardError
|
268
|
+
include ValidationError
|
269
|
+
end
|
270
|
+
|
271
|
+
# Raised when the logged user doesn't have the right to perform the query.
|
272
|
+
#
|
273
|
+
# @see https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v1.spec#L624-L625 Description of Unauthorized Error in Apache Cassandra native protocol spec v1
|
274
|
+
class UnauthorizedError < ::StandardError
|
275
|
+
include ValidationError
|
276
|
+
end
|
277
|
+
|
278
|
+
# Raised when the query is syntactically correct but invalid.
|
279
|
+
#
|
280
|
+
# @example Creating a table without selecting a keyspace
|
281
|
+
# begin
|
282
|
+
# session.execute("CREATE TABLE users (user_id INT PRIMARY KEY)")
|
283
|
+
# rescue Cassandra::Errors::InvalidError
|
284
|
+
# end
|
285
|
+
#
|
286
|
+
# @see https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v1.spec#L626 Description of Invalid Error in Apache Cassandra native protocol spec v1
|
287
|
+
class InvalidError < ::StandardError
|
288
|
+
include ValidationError
|
289
|
+
end
|
290
|
+
|
291
|
+
# Raised when the query is invalid because of some configuration issue.
|
292
|
+
#
|
293
|
+
# @example Dropping non-existent keyspace
|
294
|
+
# begin
|
295
|
+
# client.execute("DROP KEYSPACE unknown_keyspace")
|
296
|
+
# rescue Cassandra::Errors::ConfigurationError
|
297
|
+
# end
|
298
|
+
#
|
299
|
+
# @see https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v1.spec#L627 Description of Config Error in Apache Cassandra native protocol spec v1
|
300
|
+
class ConfigurationError < ::StandardError
|
301
|
+
include ValidationError
|
302
|
+
end
|
303
|
+
|
304
|
+
# Raised when the query attempted to create a keyspace or a table that was
|
305
|
+
# already existing.
|
306
|
+
#
|
307
|
+
# @example Creating a table twice
|
308
|
+
# session.execute("USE my_keyspace")
|
309
|
+
# session.execute("CREATE TABLE users (user_id INT PRIMARY KEY)")
|
310
|
+
# begin
|
311
|
+
# session.execute("CREATE TABLE users (user_id INT PRIMARY KEY)")
|
312
|
+
# rescue Cassandra::Errors::AlreadyExistsError => e
|
313
|
+
# p ['already exists', e.keyspace, e.table]
|
314
|
+
# end
|
315
|
+
#
|
316
|
+
# @see https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v1.spec#L628-L637 Description of Already Exists Error in Apache Cassandra native protocol spec v1
|
317
|
+
class AlreadyExistsError < ConfigurationError
|
318
|
+
# @return [String] keyspace
|
319
|
+
attr_reader :keyspace
|
320
|
+
|
321
|
+
# @return [String, nil] table or `nil`
|
322
|
+
attr_reader :table
|
323
|
+
|
324
|
+
# @private
|
325
|
+
def initialize(message, statement, keyspace, table)
|
326
|
+
super(message, statement)
|
327
|
+
|
328
|
+
@keyspace = keyspace
|
329
|
+
@table = table
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
# This error is thrown when all attempted hosts raised a
|
334
|
+
# {Cassandra::Errors::HostError} during connection or query execution.
|
335
|
+
#
|
336
|
+
# @see Cassandra::Cluster#connect
|
337
|
+
# @see Cassandra::Session#execute
|
338
|
+
class NoHostsAvailable < ::StandardError
|
339
|
+
include Error
|
340
|
+
|
341
|
+
# @return [Hash{Cassandra::Host => Cassandra::Errors::HostError}] a map
|
342
|
+
# of hosts to underlying exceptions
|
343
|
+
attr_reader :errors
|
344
|
+
|
345
|
+
# @private
|
346
|
+
def initialize(errors = nil)
|
347
|
+
if errors
|
348
|
+
first = true
|
349
|
+
message = "All attempted hosts failed"
|
350
|
+
details = errors.each do |(host, error)|
|
351
|
+
if first
|
352
|
+
first = false
|
353
|
+
message << ': '
|
354
|
+
else
|
355
|
+
message << ', '
|
356
|
+
end
|
357
|
+
message << "#{host.ip} (#{error.class.name}: #{error.message})"
|
358
|
+
end
|
359
|
+
else
|
360
|
+
message = "All hosts down"
|
361
|
+
end
|
362
|
+
|
363
|
+
super(message)
|
364
|
+
|
365
|
+
@errors = errors || {}
|
366
|
+
end
|
367
|
+
end
|
78
368
|
end
|
79
369
|
end
|