cassandra-driver 1.0.0.beta.3 → 1.0.0.rc.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 +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
|