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,154 @@
|
|
|
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
|
+
module Retry
|
|
21
|
+
# @abstract Actual retry policies supplied as `:retry_policy` option to
|
|
22
|
+
# {Cassandra.cluster} don't need to inherit this class, only implement
|
|
23
|
+
# its methods. This class exists for documentation purposes only.
|
|
24
|
+
module Policy
|
|
25
|
+
# Decides wether to retry a read and at what consistency level.
|
|
26
|
+
#
|
|
27
|
+
# @note this method may be called even if required_responses >= received
|
|
28
|
+
# responses if data_present is false.
|
|
29
|
+
#
|
|
30
|
+
# @param statement [Cassandra::Statement] the original statement that timed out
|
|
31
|
+
# @param consistency [Symbol] the original consistency level for the
|
|
32
|
+
# request, one of {Cassandra::CONSISTENCIES}
|
|
33
|
+
# @param required [Integer] the number of responses required to achieve
|
|
34
|
+
# requested consistency level
|
|
35
|
+
# @param received [Integer] the number of responses received by the time
|
|
36
|
+
# the query timed out
|
|
37
|
+
# @param retrieved [Boolean] whether actual data (as opposed to data
|
|
38
|
+
# checksum) was present in the received responses.
|
|
39
|
+
# @param retries [Integer] the number of retries already performed
|
|
40
|
+
#
|
|
41
|
+
# @return [Cassandra::Policies::Retry::Decision] a retry decision
|
|
42
|
+
#
|
|
43
|
+
# @see Cassandra::Retry::Policy#try_again
|
|
44
|
+
# @see Cassandra::Retry::Policy#reraise
|
|
45
|
+
# @see Cassandra::Retry::Policy#ignore
|
|
46
|
+
def read_timeout(statement, consistency, required, received, retrieved, retries)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Decides wether to retry a write and at what consistency level.
|
|
50
|
+
#
|
|
51
|
+
# @param statement [Cassandra::Statement] the original statement that timed out
|
|
52
|
+
# @param consistency [Symbol] the original consistency level for the
|
|
53
|
+
# request, one of {Cassandra::CONSISTENCIES}
|
|
54
|
+
# @param type [Symbol] One of {Cassandra::WRITE_TYPES}
|
|
55
|
+
# @param required [Integer] the number of acks required to achieve
|
|
56
|
+
# requested consistency level
|
|
57
|
+
# @param received [Integer] the number of acks received by the time the
|
|
58
|
+
# query timed out
|
|
59
|
+
# @param retries [Integer] the number of retries already performed
|
|
60
|
+
#
|
|
61
|
+
# @return [Cassandra::Policies::Retry::Decision] a retry decision
|
|
62
|
+
#
|
|
63
|
+
# @see Cassandra::Retry::Policy#try_again
|
|
64
|
+
# @see Cassandra::Retry::Policy#reraise
|
|
65
|
+
# @see Cassandra::Retry::Policy#ignore
|
|
66
|
+
def write_timeout(statement, consistency, type, required, received, retries)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Decides wether to retry and at what consistency level on an Unavailable
|
|
70
|
+
# exception.
|
|
71
|
+
#
|
|
72
|
+
# @param statement [Cassandra::Statement] the original Statement that timed out
|
|
73
|
+
# @param consistency [Symbol] the original consistency level for the
|
|
74
|
+
# request, one of {Cassandra::CONSISTENCIES}
|
|
75
|
+
# @param required [Integer] the number of replicas required to achieve
|
|
76
|
+
# requested consistency level
|
|
77
|
+
# @param alive [Integer] the number of replicas available for the request
|
|
78
|
+
# @param retries [Integer] the number of retries already performed
|
|
79
|
+
#
|
|
80
|
+
# @return [Cassandra::Policies::Retry::Decision] a retry decision
|
|
81
|
+
#
|
|
82
|
+
# @see Cassandra::Retry::Policy#try_again
|
|
83
|
+
# @see Cassandra::Retry::Policy#reraise
|
|
84
|
+
# @see Cassandra::Retry::Policy#ignore
|
|
85
|
+
def unavailable(statement, consistency, required, alive, retries)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
private
|
|
89
|
+
|
|
90
|
+
# Returns a decision that signals retry at a given consistency
|
|
91
|
+
#
|
|
92
|
+
# @param consistency [Symbol] consistency level for the retry, one of
|
|
93
|
+
# {Cassandra::CONSISTENCIES}
|
|
94
|
+
# @return [Cassandra::Policies::Retry::Decision] tell driver to retry
|
|
95
|
+
def try_again(consistency)
|
|
96
|
+
Decisions::Retry.new(consistency)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Returns a decision that signals to driver to reraise original error to
|
|
100
|
+
# the application
|
|
101
|
+
#
|
|
102
|
+
# @return [Cassandra::Policies::Retry::Decision] tell driver to reraise
|
|
103
|
+
def reraise
|
|
104
|
+
DECISION_RERAISE
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Returns a decision that signals to driver to ignore the error
|
|
108
|
+
#
|
|
109
|
+
# @return [Cassandra::Policies::Retry::Decision] tell driver to ignore
|
|
110
|
+
# the error and return an empty result to the application
|
|
111
|
+
def ignore
|
|
112
|
+
DECISION_IGNORE
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Returns a decision that signals to the driver attempt execution on the
|
|
116
|
+
# next host in the load balancing plan
|
|
117
|
+
#
|
|
118
|
+
# @return [Cassandra::Policies::Retry::Decision] tell the driver to
|
|
119
|
+
# re-execute the statement on another host
|
|
120
|
+
def try_next_host
|
|
121
|
+
DECISION_TRY_NEXT_HOST
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# @private
|
|
126
|
+
module Decisions
|
|
127
|
+
class Retry
|
|
128
|
+
attr_reader :consistency
|
|
129
|
+
|
|
130
|
+
def initialize(consistency)
|
|
131
|
+
@consistency = consistency
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
class Reraise
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
class Ignore
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
class TryNextHost
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# @private
|
|
146
|
+
DECISION_RERAISE = Decisions::Reraise.new
|
|
147
|
+
# @private
|
|
148
|
+
DECISION_IGNORE = Decisions::Ignore.new
|
|
149
|
+
# @private
|
|
150
|
+
DECISION_TRY_NEXT_HOST = Decisions::TryNextHost.new
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
require 'cassandra/retry/policies'
|
|
@@ -0,0 +1,21 @@
|
|
|
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
|
+
require 'cassandra/retry/policies/default'
|
|
20
|
+
require 'cassandra/retry/policies/downgrading_consistency'
|
|
21
|
+
require 'cassandra/retry/policies/fallthrough'
|
|
@@ -0,0 +1,53 @@
|
|
|
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
|
+
module Retry
|
|
21
|
+
module Policies
|
|
22
|
+
class Default
|
|
23
|
+
include Policy
|
|
24
|
+
|
|
25
|
+
def read_timeout(statement, consistency, required, received, retrieved, retries)
|
|
26
|
+
return reraise if retries > 0
|
|
27
|
+
|
|
28
|
+
if received >= required && !retrieved
|
|
29
|
+
try_again(consistency)
|
|
30
|
+
else
|
|
31
|
+
try_next_host
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def write_timeout(statement, consistency, type, required, received, retries)
|
|
36
|
+
return reraise if retries > 0
|
|
37
|
+
|
|
38
|
+
if statement.idempotent? && received.zero?
|
|
39
|
+
try_next_host
|
|
40
|
+
elsif type == :batch_log
|
|
41
|
+
try_again(consistency)
|
|
42
|
+
else
|
|
43
|
+
reraise
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def unavailable(statement, consistency, required, alive, retries)
|
|
48
|
+
try_next_host
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,73 @@
|
|
|
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
|
+
module Retry
|
|
21
|
+
module Policies
|
|
22
|
+
class DowngradingConsistency
|
|
23
|
+
include Policy
|
|
24
|
+
|
|
25
|
+
def read_timeout(statement, consistency, required, received, retrieved, retries)
|
|
26
|
+
return reraise if retries > 0 || SERIAL_CONSISTENCIES.include?(consistency)
|
|
27
|
+
return max_likely_to_work(consistency, required, received) if received < required
|
|
28
|
+
|
|
29
|
+
retrieved ? reraise : try_again(consistency)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def write_timeout(statement, consistency, type, required, received, retries)
|
|
33
|
+
return reraise if retries > 0
|
|
34
|
+
|
|
35
|
+
case type
|
|
36
|
+
when :simple, :batch
|
|
37
|
+
ignore
|
|
38
|
+
when :unlogged_batch
|
|
39
|
+
max_likely_to_work(consistency, required, received)
|
|
40
|
+
when :batch_log
|
|
41
|
+
try_again(consistency)
|
|
42
|
+
else
|
|
43
|
+
reraise
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def unavailable(statement, consistency, required, alive, retries)
|
|
48
|
+
return reraise if retries > 0
|
|
49
|
+
|
|
50
|
+
max_likely_to_work(consistency, required, alive)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
def max_likely_to_work(consistency, required, received)
|
|
56
|
+
if consistency == :all &&
|
|
57
|
+
required > 1 &&
|
|
58
|
+
received >= (required.to_f / 2).floor + 1
|
|
59
|
+
try_again(:quorum)
|
|
60
|
+
elsif received >= 3
|
|
61
|
+
try_again(:three)
|
|
62
|
+
elsif received >= 2
|
|
63
|
+
try_again(:two)
|
|
64
|
+
elsif received >= 1
|
|
65
|
+
try_again(:one)
|
|
66
|
+
else
|
|
67
|
+
reraise
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
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
|
+
module Retry
|
|
21
|
+
module Policies
|
|
22
|
+
class Fallthrough
|
|
23
|
+
include Policy
|
|
24
|
+
|
|
25
|
+
def read_timeout(statement, consistency, required, received, retrieved, retries)
|
|
26
|
+
reraise
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def write_timeout(statement, consistency, type, required, received, retries)
|
|
30
|
+
reraise
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def unavailable(statement, consistency, required, alive, retries)
|
|
34
|
+
reraise
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,270 @@
|
|
|
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
|
+
# Sessions are used for query execution. Each session tracks its current keyspace.
|
|
21
|
+
# A session should be reused as much as possible, however it is ok to create several
|
|
22
|
+
# independent session for interacting with different keyspaces in the same application.
|
|
23
|
+
class Session
|
|
24
|
+
extend Forwardable
|
|
25
|
+
|
|
26
|
+
# @!method keyspace
|
|
27
|
+
# Returns current keyspace
|
|
28
|
+
# @return [String] current keyspace
|
|
29
|
+
def_delegators :@client, :keyspace
|
|
30
|
+
|
|
31
|
+
# @private
|
|
32
|
+
def initialize(client, default_options, futures_factory, profile_manager)
|
|
33
|
+
@client = client
|
|
34
|
+
@options = default_options
|
|
35
|
+
@futures = futures_factory
|
|
36
|
+
@profile_manager = profile_manager
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Executes a given statement and returns a future result
|
|
40
|
+
#
|
|
41
|
+
# @param statement [String, Cassandra::Statements::Simple,
|
|
42
|
+
# Cassandra::Statements::Bound, Cassandra::Statements::Prepared]
|
|
43
|
+
# statement to execute
|
|
44
|
+
#
|
|
45
|
+
# @param options [Hash] (nil) a customizable set of options
|
|
46
|
+
#
|
|
47
|
+
# @option options [Symbol] :consistency consistency level for the request.
|
|
48
|
+
# Must be one of {Cassandra::CONSISTENCIES}. Defaults to the setting in the
|
|
49
|
+
# active execution profile. If none is specified, the default profile is used,
|
|
50
|
+
# which is set to `:quorum`.
|
|
51
|
+
# @option options [Integer] :page_size size of results page. You can page
|
|
52
|
+
# through results using {Cassandra::Result#next_page} or
|
|
53
|
+
# {Cassandra::Result#next_page_async}
|
|
54
|
+
# @option options [Boolean] :trace (false) whether to enable request tracing
|
|
55
|
+
# @option options [Numeric] :timeout (nil) if specified, it is a number of
|
|
56
|
+
# seconds after which to time out the request if it hasn't completed. Defaults to the setting in the
|
|
57
|
+
# active execution profile. If none is specified, the default profile is used,
|
|
58
|
+
# which is set to 12 seconds.
|
|
59
|
+
# @option options [Symbol] :serial_consistency (nil) this option is only
|
|
60
|
+
# relevant for conditional updates and specifies a serial consistency to
|
|
61
|
+
# be used, one of {Cassandra::SERIAL_CONSISTENCIES}
|
|
62
|
+
# @option options [String] :paging_state (nil) this option is used for
|
|
63
|
+
# stateless paging, where result paging is resumed some time after the
|
|
64
|
+
# initial request.
|
|
65
|
+
# @option options [Array, Hash] :arguments (nil) positional or named
|
|
66
|
+
# arguments for the statement.
|
|
67
|
+
# @option options [Array, Hash] :type_hints (nil) override Util.guess_type
|
|
68
|
+
# to determine the CQL type for an argument; nil elements will fall-back
|
|
69
|
+
# to Util.guess_type.
|
|
70
|
+
# @option options [Boolean] :idempotent (false) specify whether this
|
|
71
|
+
# statement can be retried safely on timeout.
|
|
72
|
+
# @option options [Hash<[String, Symbol], String>] :payload (nil) custom
|
|
73
|
+
# outgoing payload to be sent with the request.
|
|
74
|
+
# @option options [String, Symbol] :execution_profile (nil) name of {Cassandra::Execution::Profile}
|
|
75
|
+
# from which to obtain certain query options. Defaults to the cluster's default execution profile.
|
|
76
|
+
#
|
|
77
|
+
# @see Cassandra.cluster Options that can be specified on the cluster-level
|
|
78
|
+
# and their default values.
|
|
79
|
+
#
|
|
80
|
+
# @note Positional arguments for simple statements are only supported
|
|
81
|
+
# starting with Apache Cassandra 2.0 and above.
|
|
82
|
+
#
|
|
83
|
+
# @note Named arguments for simple statements are only supported
|
|
84
|
+
# starting with Apache Cassandra 2.1 and above.
|
|
85
|
+
#
|
|
86
|
+
# @return [Cassandra::Future<Cassandra::Result>]
|
|
87
|
+
#
|
|
88
|
+
# @see Cassandra::Session#execute A list of errors this future can be resolved with
|
|
89
|
+
def execute_async(statement, options = nil)
|
|
90
|
+
options = merge_execution_options(options)
|
|
91
|
+
|
|
92
|
+
case statement
|
|
93
|
+
when ::String
|
|
94
|
+
Statements::Simple.new(statement,
|
|
95
|
+
options.arguments,
|
|
96
|
+
options.type_hints,
|
|
97
|
+
options.idempotent?).accept(@client,
|
|
98
|
+
options)
|
|
99
|
+
when Statement
|
|
100
|
+
statement.accept(@client, options)
|
|
101
|
+
else
|
|
102
|
+
@futures.error(::ArgumentError.new("unsupported statement #{statement.inspect}"))
|
|
103
|
+
end
|
|
104
|
+
rescue => e
|
|
105
|
+
@futures.error(e)
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# @!method execute(statement, options = nil)
|
|
109
|
+
# A blocking wrapper around {Cassandra::Session#execute_async}
|
|
110
|
+
#
|
|
111
|
+
# @param statement [String, Cassandra::Statements::Simple,
|
|
112
|
+
# Cassandra::Statements::Bound, Cassandra::Statements::Prepared]
|
|
113
|
+
# statement to execute
|
|
114
|
+
#
|
|
115
|
+
# @param options [Hash] (nil) a customizable set of options. See {#execute_async} for details.
|
|
116
|
+
#
|
|
117
|
+
# @see Cassandra::Session#execute_async
|
|
118
|
+
# @see Cassandra::Future#get
|
|
119
|
+
#
|
|
120
|
+
# @return [Cassandra::Result] query result
|
|
121
|
+
# @raise [Cassandra::Errors::NoHostsAvailable] if all hosts fail
|
|
122
|
+
# @raise [Cassandra::Errors::ExecutionError] if Cassandra fails to execute
|
|
123
|
+
# @raise [Cassandra::Errors::ValidationError] if Cassandra fails to validate
|
|
124
|
+
# @raise [Cassandra::Errors::TimeoutError] if request has not completed
|
|
125
|
+
# within the `:timeout` given
|
|
126
|
+
def execute(statement, options = nil)
|
|
127
|
+
execute_async(statement, options).get
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Prepares a given statement and returns a future prepared statement
|
|
131
|
+
#
|
|
132
|
+
# @param statement [String, Cassandra::Statements::Simple] a statement to
|
|
133
|
+
# prepare
|
|
134
|
+
#
|
|
135
|
+
# @param options [Hash] (nil) a customizable set of options
|
|
136
|
+
#
|
|
137
|
+
# @option options [Boolean] :trace (false) whether to enable request tracing
|
|
138
|
+
# @option options [Numeric] :timeout (nil) if specified, it is a number of
|
|
139
|
+
# seconds after which to time out the request if it hasn't completed
|
|
140
|
+
# @option options [Boolean] :idempotent (false) specify whether the
|
|
141
|
+
# statement being prepared can be retried safely on timeout during
|
|
142
|
+
# execution.
|
|
143
|
+
# @option options [String, Symbol] :execution_profile (nil) name of {Cassandra::Execution::Profile}
|
|
144
|
+
# from which to obtain certain query options. Defaults to the cluster's default execution profile.
|
|
145
|
+
#
|
|
146
|
+
# @return [Cassandra::Future<Cassandra::Statements::Prepared>] future
|
|
147
|
+
# prepared statement
|
|
148
|
+
def prepare_async(statement, options = nil)
|
|
149
|
+
options = merge_execution_options(options)
|
|
150
|
+
|
|
151
|
+
case statement
|
|
152
|
+
when ::String
|
|
153
|
+
@client.prepare(statement, options)
|
|
154
|
+
when Statements::Simple
|
|
155
|
+
@client.prepare(statement.cql, options)
|
|
156
|
+
else
|
|
157
|
+
@futures.error(::ArgumentError.new("unsupported statement #{statement.inspect}"))
|
|
158
|
+
end
|
|
159
|
+
rescue => e
|
|
160
|
+
@futures.error(e)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# A blocking wrapper around {Cassandra::Session#prepare_async}
|
|
164
|
+
#
|
|
165
|
+
# @param statement [String, Cassandra::Statements::Simple] a statement to
|
|
166
|
+
# prepare
|
|
167
|
+
#
|
|
168
|
+
# @param options [Hash] (nil) a customizable set of options. See {#prepare_async} for details.
|
|
169
|
+
#
|
|
170
|
+
# @see Cassandra::Session#prepare_async
|
|
171
|
+
# @see Cassandra::Future#get
|
|
172
|
+
#
|
|
173
|
+
# @return [Cassandra::Statements::Prepared] prepared statement
|
|
174
|
+
# @raise [Cassandra::Errors::NoHostsAvailable] if none of the hosts can be reached
|
|
175
|
+
# @raise [Cassandra::Errors::ExecutionError] if Cassandra returns an error response
|
|
176
|
+
def prepare(statement, options = nil)
|
|
177
|
+
prepare_async(statement, options).get
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Returns a logged {Statements::Batch} instance and optionally yields it to
|
|
181
|
+
# a given block
|
|
182
|
+
# @yieldparam batch [Statements::Batch] a logged batch
|
|
183
|
+
# @return [Statements::Batch] a logged batch
|
|
184
|
+
def logged_batch(&block)
|
|
185
|
+
statement = Statements::Batch::Logged.new(@options)
|
|
186
|
+
yield(statement) if block_given?
|
|
187
|
+
statement
|
|
188
|
+
end
|
|
189
|
+
alias batch logged_batch
|
|
190
|
+
|
|
191
|
+
# Returns a unlogged {Statements::Batch} instance and optionally yields it
|
|
192
|
+
# to a given block
|
|
193
|
+
# @yieldparam batch [Statements::Batch] an unlogged batch
|
|
194
|
+
# @return [Statements::Batch] an unlogged batch
|
|
195
|
+
def unlogged_batch
|
|
196
|
+
statement = Statements::Batch::Unlogged.new(@options)
|
|
197
|
+
yield(statement) if block_given?
|
|
198
|
+
statement
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# Returns a counter {Statements::Batch} instance and optionally yields it
|
|
202
|
+
# to a given block
|
|
203
|
+
# @yieldparam batch [Statements::Batch] a counter batch
|
|
204
|
+
# @return [Statements::Batch] a counter batch
|
|
205
|
+
def counter_batch
|
|
206
|
+
statement = Statements::Batch::Counter.new(@options)
|
|
207
|
+
yield(statement) if block_given?
|
|
208
|
+
statement
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# Asynchronously closes current session
|
|
212
|
+
#
|
|
213
|
+
# @return [Cassandra::Future<Cassandra::Session>] a future that resolves to
|
|
214
|
+
# self once closed
|
|
215
|
+
def close_async
|
|
216
|
+
promise = @futures.promise
|
|
217
|
+
|
|
218
|
+
@client.close.on_complete do |f|
|
|
219
|
+
if f.resolved?
|
|
220
|
+
promise.fulfill(self)
|
|
221
|
+
else
|
|
222
|
+
f.on_failure {|e| promise.break(e)}
|
|
223
|
+
end
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
promise.future
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
# Synchronously closes current session
|
|
230
|
+
#
|
|
231
|
+
# @return [self] this session
|
|
232
|
+
#
|
|
233
|
+
# @see Cassandra::Session#close_async
|
|
234
|
+
def close
|
|
235
|
+
close_async.get
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
# @private
|
|
239
|
+
def inspect
|
|
240
|
+
"#<#{self.class.name}:0x#{object_id.to_s(16)} " \
|
|
241
|
+
"@keyspace=#{keyspace.inspect}, " \
|
|
242
|
+
"@options=#{@options.inspect}>"
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
private
|
|
246
|
+
|
|
247
|
+
# @private
|
|
248
|
+
def merge_execution_options(options)
|
|
249
|
+
if options
|
|
250
|
+
Util.assert_instance_of(::Hash, options)
|
|
251
|
+
# Yell if the caller gave us a bad profile name.
|
|
252
|
+
execution_profile = nil
|
|
253
|
+
if options.key?(:execution_profile)
|
|
254
|
+
execution_profile = @profile_manager.profiles[options[:execution_profile]]
|
|
255
|
+
raise ::ArgumentError.new("Unknown execution profile #{options[:execution_profile]}") unless execution_profile
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
# This looks a little hokey, so let's explain: Execution::Options.override takes a
|
|
259
|
+
# varargs-style array of things to merge into the base options object (to produce
|
|
260
|
+
# a new Options object, not mutate the base). If an execution profile was specified,
|
|
261
|
+
# we want its attributes to override the base options. In addition, if individual options
|
|
262
|
+
# were specified, we want *those* to take precedence over the execution profile attributes.
|
|
263
|
+
# So we override in this order.
|
|
264
|
+
@options.override(execution_profile, options)
|
|
265
|
+
else
|
|
266
|
+
@options
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
end
|