cassandra-driver 2.1.3-java → 2.1.4-java
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 +4 -4
- data/README.md +1 -1
- data/lib/cassandra.rb +19 -4
- data/lib/cassandra/cluster/client.rb +27 -20
- data/lib/cassandra/cluster/connector.rb +7 -0
- data/lib/cassandra/cluster/control_connection.rb +4 -1
- data/lib/cassandra/cluster/metadata.rb +16 -6
- data/lib/cassandra/cluster/options.rb +11 -1
- data/lib/cassandra/cluster/schema.rb +1 -1
- data/lib/cassandra/cluster/schema/replication_strategies/network_topology.rb +44 -35
- data/lib/cassandra/cluster/schema/type_parser.rb +7 -1
- data/lib/cassandra/compression.rb +3 -0
- data/lib/cassandra/compression/compressors/lz4.rb +8 -6
- data/lib/cassandra/compression/compressors/snappy.rb +8 -6
- data/lib/cassandra/driver.rb +10 -2
- data/lib/cassandra/protocol/cql_byte_buffer.rb +4 -0
- data/lib/cassandra/protocol/requests/batch_request.rb +14 -3
- data/lib/cassandra/protocol/requests/execute_request.rb +9 -2
- data/lib/cassandra/protocol/requests/query_request.rb +12 -3
- data/lib/cassandra/types.rb +6 -1
- data/lib/cassandra/version.rb +1 -1
- data/lib/cassandra_murmur3.jar +0 -0
- data/lib/datastax/cassandra.rb +44 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 32c86970c749f6a1afe3c4af85e2d16eb62c11f9
|
|
4
|
+
data.tar.gz: 97c1cacbbffa03e9d1162dce3bbf0a1929b02af2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 52a010f2c3254b953ff1d9af072ecba957def21236fafa3467029ef1fa4a50428c8179a5ee9cc5b9a421082347ad45da07966512bc8cf012fa687578eabcada9
|
|
7
|
+
data.tar.gz: 85094e7b051ae8c91c1b6caf8669383e4671ccb18095f6265c6aff8270f47fe0debde9465042e2bb1ec8070f29e8fd66d5bd6f6d6dd132ea5d54a1e99e5cf121
|
data/README.md
CHANGED
|
@@ -154,7 +154,7 @@ Please [refer to the usage documentation for more information on common pitfalls
|
|
|
154
154
|
|
|
155
155
|
## Contributing
|
|
156
156
|
|
|
157
|
-
For contributing read [CONTRIBUTING.md](https://github.com/datastax/ruby-driver/blob/master/
|
|
157
|
+
For contributing read [CONTRIBUTING.md](https://github.com/datastax/ruby-driver/blob/master/CONTRIBUTING.md)
|
|
158
158
|
|
|
159
159
|
## Credits
|
|
160
160
|
|
data/lib/cassandra.rb
CHANGED
|
@@ -59,6 +59,9 @@ module Cassandra
|
|
|
59
59
|
#
|
|
60
60
|
# @option options [Integer] :port (9042) cassandra native protocol port.
|
|
61
61
|
#
|
|
62
|
+
# @option options [Boolean] :nodelay (false) when set to `true`, disables
|
|
63
|
+
# nagle algorithm.
|
|
64
|
+
#
|
|
62
65
|
# @option options [String] :datacenter (nil) name of current datacenter.
|
|
63
66
|
# First datacenter found will be assumed current by default. Note that you
|
|
64
67
|
# can skip this option if you specify only hosts from the local datacenter
|
|
@@ -122,6 +125,12 @@ module Cassandra
|
|
|
122
125
|
# address resolver to use. Must be one of `:none` or
|
|
123
126
|
# `:ec2_multi_region`.
|
|
124
127
|
#
|
|
128
|
+
# @option options [Boolean] :client_timestamps (false) whether the driver
|
|
129
|
+
# should send timestamps for each executed statement. Enabling this setting
|
|
130
|
+
# allows mitigating Cassandra cluster clock skew because the timestamp of
|
|
131
|
+
# the client machine will be used. This does not help mitigate application
|
|
132
|
+
# cluster clock skew.
|
|
133
|
+
#
|
|
125
134
|
# @option options [Boolean] :synchronize_schema (true) whether the driver
|
|
126
135
|
# should automatically keep schema metadata synchronized. When enabled, the
|
|
127
136
|
# driver updates schema metadata after receiving schema change
|
|
@@ -217,7 +226,7 @@ module Cassandra
|
|
|
217
226
|
:connect_timeout, :futures_factory, :datacenter, :address_resolution,
|
|
218
227
|
:address_resolution_policy, :idle_timeout, :heartbeat_interval, :timeout,
|
|
219
228
|
:synchronize_schema, :schema_refresh_delay, :schema_refresh_timeout,
|
|
220
|
-
:shuffle_replicas
|
|
229
|
+
:shuffle_replicas, :client_timestamps
|
|
221
230
|
].include?(key)
|
|
222
231
|
end
|
|
223
232
|
|
|
@@ -315,10 +324,8 @@ module Cassandra
|
|
|
315
324
|
|
|
316
325
|
case compression
|
|
317
326
|
when :snappy
|
|
318
|
-
require 'cassandra/compression/compressors/snappy'
|
|
319
327
|
options[:compressor] = Compression::Compressors::Snappy.new
|
|
320
328
|
when :lz4
|
|
321
|
-
require 'cassandra/compression/compressors/lz4'
|
|
322
329
|
options[:compressor] = Compression::Compressors::Lz4.new
|
|
323
330
|
else
|
|
324
331
|
raise ::ArgumentError, ":compression must be either :snappy or :lz4, #{compression.inspect} given"
|
|
@@ -429,6 +436,10 @@ module Cassandra
|
|
|
429
436
|
Util.assert_one_of(CONSISTENCIES, consistency) { ":consistency must be one of #{CONSISTENCIES.inspect}, #{consistency.inspect} given" }
|
|
430
437
|
end
|
|
431
438
|
|
|
439
|
+
if options.has_key?(:nodelay)
|
|
440
|
+
options[:nodelay] = !!options[:nodelay]
|
|
441
|
+
end
|
|
442
|
+
|
|
432
443
|
if options.has_key?(:trace)
|
|
433
444
|
options[:trace] = !!options[:trace]
|
|
434
445
|
end
|
|
@@ -476,6 +487,10 @@ module Cassandra
|
|
|
476
487
|
options[:synchronize_schema] = !!options[:synchronize_schema]
|
|
477
488
|
end
|
|
478
489
|
|
|
490
|
+
if options.has_key?(:client_timestamps)
|
|
491
|
+
options[:client_timestamps] = !!options[:client_timestamps]
|
|
492
|
+
end
|
|
493
|
+
|
|
479
494
|
hosts = []
|
|
480
495
|
|
|
481
496
|
Array(options.fetch(:hosts, '127.0.0.1')).each do |host|
|
|
@@ -497,7 +512,7 @@ module Cassandra
|
|
|
497
512
|
|
|
498
513
|
hosts.shuffle!
|
|
499
514
|
rescue => e
|
|
500
|
-
futures = options.fetch(:futures_factory) {
|
|
515
|
+
futures = options.fetch(:futures_factory) { return Future::Error.new(e) }
|
|
501
516
|
futures.error(e)
|
|
502
517
|
else
|
|
503
518
|
driver = Driver.new(options)
|
|
@@ -207,9 +207,11 @@ module Cassandra
|
|
|
207
207
|
def query(statement, options)
|
|
208
208
|
return @futures.error(Errors::ClientError.new("Positional arguments are not supported by the current version of Apache Cassandra")) if !statement.params.empty? && @connection_options.protocol_version == 1
|
|
209
209
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
210
|
+
timestamp = nil
|
|
211
|
+
timestamp = Time.now if @connection_options.client_timestamps? && @connection_options.protocol_version > 2
|
|
212
|
+
request = Protocol::QueryRequest.new(statement.cql, statement.params, statement.params_types, options.consistency, options.serial_consistency, options.page_size, options.paging_state, options.trace?, statement.params_names, timestamp)
|
|
213
|
+
timeout = options.timeout
|
|
214
|
+
promise = @futures.promise
|
|
213
215
|
|
|
214
216
|
keyspace = @keyspace
|
|
215
217
|
plan = @load_balancing_policy.plan(keyspace, statement, options)
|
|
@@ -234,9 +236,11 @@ module Cassandra
|
|
|
234
236
|
end
|
|
235
237
|
|
|
236
238
|
def execute(statement, options)
|
|
239
|
+
timestamp = nil
|
|
240
|
+
timestamp = Time.now if @connection_options.client_timestamps? && @connection_options.protocol_version > 2
|
|
237
241
|
timeout = options.timeout
|
|
238
242
|
result_metadata = statement.result_metadata
|
|
239
|
-
request = Protocol::ExecuteRequest.new(nil, statement.params_types, statement.params, result_metadata.nil?, options.consistency, options.serial_consistency, options.page_size, options.paging_state, options.trace
|
|
243
|
+
request = Protocol::ExecuteRequest.new(nil, statement.params_types, statement.params, result_metadata.nil?, options.consistency, options.serial_consistency, options.page_size, options.paging_state, options.trace?, timestamp)
|
|
240
244
|
promise = @futures.promise
|
|
241
245
|
|
|
242
246
|
keyspace = @keyspace
|
|
@@ -250,12 +254,15 @@ module Cassandra
|
|
|
250
254
|
def batch(statement, options)
|
|
251
255
|
return @futures.error(Errors::ClientError.new("Batch statements are not supported by the current version of Apache Cassandra")) if @connection_options.protocol_version < 2
|
|
252
256
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
+
timestamp = nil
|
|
258
|
+
timestamp = Time.now if @connection_options.client_timestamps? && @connection_options.protocol_version > 2
|
|
259
|
+
timeout = options.timeout
|
|
260
|
+
request = Protocol::BatchRequest.new(BATCH_TYPES[statement.type], options.consistency, options.trace?, options.serial_consistency, timestamp)
|
|
261
|
+
keyspace = @keyspace
|
|
262
|
+
plan = @load_balancing_policy.plan(keyspace, statement, options)
|
|
263
|
+
promise = @futures.promise
|
|
257
264
|
|
|
258
|
-
batch_by_plan(promise, keyspace, statement, options, plan, timeout)
|
|
265
|
+
batch_by_plan(promise, keyspace, statement, options, request, plan, timeout)
|
|
259
266
|
|
|
260
267
|
promise.future
|
|
261
268
|
end
|
|
@@ -509,7 +516,7 @@ module Cassandra
|
|
|
509
516
|
end
|
|
510
517
|
end
|
|
511
518
|
|
|
512
|
-
def batch_by_plan(promise, keyspace, statement, options, plan, timeout, errors = nil, hosts = [])
|
|
519
|
+
def batch_by_plan(promise, keyspace, statement, options, request, plan, timeout, errors = nil, hosts = [])
|
|
513
520
|
unless plan.has_next?
|
|
514
521
|
promise.break(Errors::NoHostsAvailable.new(errors))
|
|
515
522
|
return
|
|
@@ -522,7 +529,7 @@ module Cassandra
|
|
|
522
529
|
unless pool
|
|
523
530
|
errors ||= {}
|
|
524
531
|
errors[host] = NOT_CONNECTED
|
|
525
|
-
return batch_by_plan(promise, keyspace, statement, options, plan, timeout, errors, hosts)
|
|
532
|
+
return batch_by_plan(promise, keyspace, statement, options, request, plan, timeout, errors, hosts)
|
|
526
533
|
end
|
|
527
534
|
|
|
528
535
|
connection = pool.random_connection
|
|
@@ -531,14 +538,14 @@ module Cassandra
|
|
|
531
538
|
switch = switch_keyspace(connection, keyspace, timeout)
|
|
532
539
|
switch.on_complete do |s|
|
|
533
540
|
if s.resolved?
|
|
534
|
-
batch_and_send_request_by_plan(host, connection, promise, keyspace, statement, options, plan, timeout, errors, hosts)
|
|
541
|
+
batch_and_send_request_by_plan(host, connection, promise, keyspace, statement, request, options, plan, timeout, errors, hosts)
|
|
535
542
|
else
|
|
536
543
|
s.on_failure do |e|
|
|
537
544
|
case e
|
|
538
545
|
when Errors::HostError
|
|
539
546
|
errors ||= {}
|
|
540
547
|
errors[host] = e
|
|
541
|
-
batch_by_plan(promise, keyspace, statement, options, plan, timeout, errors, hosts)
|
|
548
|
+
batch_by_plan(promise, keyspace, statement, options, request, plan, timeout, errors, hosts)
|
|
542
549
|
else
|
|
543
550
|
promise.break(e)
|
|
544
551
|
end
|
|
@@ -546,16 +553,16 @@ module Cassandra
|
|
|
546
553
|
end
|
|
547
554
|
end
|
|
548
555
|
else
|
|
549
|
-
batch_and_send_request_by_plan(host, connection, promise, keyspace, statement, options, plan, timeout, errors, hosts)
|
|
556
|
+
batch_and_send_request_by_plan(host, connection, promise, keyspace, statement, request, options, plan, timeout, errors, hosts)
|
|
550
557
|
end
|
|
551
558
|
rescue => e
|
|
552
559
|
errors ||= {}
|
|
553
560
|
errors[host] = e
|
|
554
|
-
batch_by_plan(promise, keyspace, statement, options, plan, timeout, errors, hosts)
|
|
561
|
+
batch_by_plan(promise, keyspace, statement, options, request, plan, timeout, errors, hosts)
|
|
555
562
|
end
|
|
556
563
|
|
|
557
|
-
def batch_and_send_request_by_plan(host, connection, promise, keyspace, statement, options, plan, timeout, errors, hosts)
|
|
558
|
-
request
|
|
564
|
+
def batch_and_send_request_by_plan(host, connection, promise, keyspace, statement, request, options, plan, timeout, errors, hosts)
|
|
565
|
+
request.clear
|
|
559
566
|
unprepared = Hash.new {|hash, cql| hash[cql] = []}
|
|
560
567
|
|
|
561
568
|
statement.statements.each do |statement|
|
|
@@ -598,7 +605,7 @@ module Cassandra
|
|
|
598
605
|
when Errors::HostError
|
|
599
606
|
errors ||= {}
|
|
600
607
|
errors[host] = e
|
|
601
|
-
batch_by_plan(promise, keyspace, statement, options, plan, timeout, errors, hosts)
|
|
608
|
+
batch_by_plan(promise, keyspace, statement, options, request, plan, timeout, errors, hosts)
|
|
602
609
|
else
|
|
603
610
|
promise.break(e)
|
|
604
611
|
end
|
|
@@ -711,7 +718,7 @@ module Cassandra
|
|
|
711
718
|
when Protocol::ExecuteRequest
|
|
712
719
|
execute_by_plan(promise, keyspace, statement, options, request, plan, timeout, errors, hosts)
|
|
713
720
|
when Protocol::BatchRequest
|
|
714
|
-
batch_by_plan(promise, keyspace, statement, options, plan, timeout, errors, hosts)
|
|
721
|
+
batch_by_plan(promise, keyspace, statement, options, request, plan, timeout, errors, hosts)
|
|
715
722
|
end
|
|
716
723
|
else
|
|
717
724
|
promise.break(error)
|
|
@@ -774,7 +781,7 @@ module Cassandra
|
|
|
774
781
|
when Protocol::ExecuteRequest
|
|
775
782
|
execute_by_plan(promise, keyspace, statement, options, request, plan, timeout, errors, hosts)
|
|
776
783
|
when Protocol::BatchRequest
|
|
777
|
-
batch_by_plan(promise, keyspace, statement, options, plan, timeout, errors, hosts)
|
|
784
|
+
batch_by_plan(promise, keyspace, statement, options, request, plan, timeout, errors, hosts)
|
|
778
785
|
else
|
|
779
786
|
promise.break(e)
|
|
780
787
|
end
|
|
@@ -114,6 +114,13 @@ module Cassandra
|
|
|
114
114
|
def do_connect(host)
|
|
115
115
|
@reactor.connect(host.ip.to_s, @connection_options.port, {:timeout => @connection_options.connect_timeout, :ssl => @connection_options.ssl}) do |connection|
|
|
116
116
|
raise Errors::ClientError, 'Not connected, reactor stopped' unless connection
|
|
117
|
+
|
|
118
|
+
if @connection_options.nodelay?
|
|
119
|
+
connection.to_io.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
|
|
120
|
+
else
|
|
121
|
+
connection.to_io.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 0)
|
|
122
|
+
end
|
|
123
|
+
|
|
117
124
|
Protocol::CqlProtocolHandler.new(connection, @reactor, @connection_options.protocol_version, @connection_options.compressor, @connection_options.heartbeat_interval, @connection_options.idle_timeout)
|
|
118
125
|
end.flat_map do |connection|
|
|
119
126
|
f = request_options(connection)
|
|
@@ -242,6 +242,8 @@ module Cassandra
|
|
|
242
242
|
def refresh_schema_async
|
|
243
243
|
connection = @connection
|
|
244
244
|
|
|
245
|
+
@logger.info("Refreshing schema")
|
|
246
|
+
|
|
245
247
|
return Ione::Future.failed(Errors::ClientError.new('Not connected')) if connection.nil?
|
|
246
248
|
|
|
247
249
|
keyspaces = send_select_request(connection, SELECT_KEYSPACES)
|
|
@@ -259,6 +261,7 @@ module Cassandra
|
|
|
259
261
|
|
|
260
262
|
@schema.update_keyspaces(host, keyspaces, tables, columns, types)
|
|
261
263
|
@metadata.rebuild_token_map
|
|
264
|
+
@logger.info("Schema refreshed")
|
|
262
265
|
end
|
|
263
266
|
end
|
|
264
267
|
|
|
@@ -674,7 +677,7 @@ Control connection failed and is unlikely to recover.
|
|
|
674
677
|
register_async
|
|
675
678
|
end
|
|
676
679
|
f = f.flat_map { refresh_hosts_async_maybe_retry }
|
|
677
|
-
f = f.flat_map { refresh_schema_async_maybe_retry }
|
|
680
|
+
f = f.flat_map { refresh_schema_async_maybe_retry } if @connection_options.synchronize_schema?
|
|
678
681
|
f = f.fallback do |error|
|
|
679
682
|
@logger.debug("Connection to #{host.ip} failed (#{error.class.name}: #{error.message})")
|
|
680
683
|
|
|
@@ -80,16 +80,22 @@ module Cassandra
|
|
|
80
80
|
|
|
81
81
|
token_ring = tokens.to_a
|
|
82
82
|
token_replicas = ::Hash.new
|
|
83
|
+
token_maps = ::Hash.new
|
|
83
84
|
|
|
84
85
|
@schema.each_keyspace do |keyspace|
|
|
85
86
|
replication = keyspace.replication
|
|
86
|
-
|
|
87
|
+
key = replication_key(replication.klass, replication.options)
|
|
88
|
+
|
|
89
|
+
unless token_maps.include?(key)
|
|
90
|
+
strategy = @strategies[replication.klass] || @default_strategy
|
|
91
|
+
token_maps[key] = strategy.replication_map(
|
|
92
|
+
token_to_host,
|
|
93
|
+
token_ring,
|
|
94
|
+
replication.options
|
|
95
|
+
)
|
|
96
|
+
end
|
|
87
97
|
|
|
88
|
-
token_replicas[keyspace.name] =
|
|
89
|
-
token_to_host,
|
|
90
|
-
token_ring,
|
|
91
|
-
replication.options
|
|
92
|
-
)
|
|
98
|
+
token_replicas[keyspace.name] = token_maps[key]
|
|
93
99
|
end
|
|
94
100
|
|
|
95
101
|
@token_replicas = token_replicas
|
|
@@ -100,6 +106,10 @@ module Cassandra
|
|
|
100
106
|
|
|
101
107
|
private
|
|
102
108
|
|
|
109
|
+
def replication_key(klass, options)
|
|
110
|
+
(klass + ':' + options.keys.sort.map {|k| "#{k}=#{options[k]}"}.join(',')).hash
|
|
111
|
+
end
|
|
112
|
+
|
|
103
113
|
def insertion_point(list, item)
|
|
104
114
|
min = 0
|
|
105
115
|
max = list.size - 1
|
|
@@ -25,7 +25,7 @@ module Cassandra
|
|
|
25
25
|
:schema_refresh_delay, :schema_refresh_timeout
|
|
26
26
|
attr_accessor :protocol_version
|
|
27
27
|
|
|
28
|
-
def initialize(protocol_version, credentials, auth_provider, compressor, port, connect_timeout, ssl, connections_per_local_node, connections_per_remote_node, heartbeat_interval, idle_timeout, synchronize_schema, schema_refresh_delay, schema_refresh_timeout)
|
|
28
|
+
def initialize(protocol_version, credentials, auth_provider, compressor, port, connect_timeout, ssl, connections_per_local_node, connections_per_remote_node, heartbeat_interval, idle_timeout, synchronize_schema, schema_refresh_delay, schema_refresh_timeout, client_timestamps, nodelay)
|
|
29
29
|
@protocol_version = protocol_version
|
|
30
30
|
@credentials = credentials
|
|
31
31
|
@auth_provider = auth_provider
|
|
@@ -38,6 +38,8 @@ module Cassandra
|
|
|
38
38
|
@synchronize_schema = synchronize_schema
|
|
39
39
|
@schema_refresh_delay = schema_refresh_delay
|
|
40
40
|
@schema_refresh_timeout = schema_refresh_timeout
|
|
41
|
+
@client_timestamps = client_timestamps
|
|
42
|
+
@nodelay = nodelay
|
|
41
43
|
|
|
42
44
|
@connections_per_local_node = connections_per_local_node
|
|
43
45
|
@connections_per_remote_node = connections_per_remote_node
|
|
@@ -47,6 +49,14 @@ module Cassandra
|
|
|
47
49
|
@synchronize_schema
|
|
48
50
|
end
|
|
49
51
|
|
|
52
|
+
def client_timestamps?
|
|
53
|
+
@client_timestamps
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def nodelay?
|
|
57
|
+
@nodelay
|
|
58
|
+
end
|
|
59
|
+
|
|
50
60
|
def compression
|
|
51
61
|
@compressor && @compressor.algorithm
|
|
52
62
|
end
|
|
@@ -385,7 +385,7 @@ module Cassandra
|
|
|
385
385
|
index = Column::Index.new(column['index_name'])
|
|
386
386
|
else
|
|
387
387
|
options = ::JSON.load(column['index_options'])
|
|
388
|
-
index = Column::Index.new(column['index_name'], options['class_name'])
|
|
388
|
+
index = Column::Index.new(column['index_name'], options && options['class_name'])
|
|
389
389
|
end
|
|
390
390
|
|
|
391
391
|
Column.new(name, type, order, index, is_static, is_frozen)
|
|
@@ -24,56 +24,65 @@ module Cassandra
|
|
|
24
24
|
# @private
|
|
25
25
|
class NetworkTopology
|
|
26
26
|
def replication_map(token_hosts, token_ring, replication_options)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
racks = ::Hash.new
|
|
28
|
+
datacenter_token_rings = ::Hash.new
|
|
29
|
+
size = token_ring.size
|
|
30
|
+
|
|
31
|
+
token_ring.each_with_index do |token, i|
|
|
32
|
+
host = token_hosts[token]
|
|
33
|
+
|
|
30
34
|
racks[host.datacenter] ||= ::Set.new
|
|
31
35
|
racks[host.datacenter].add(host.rack)
|
|
36
|
+
|
|
37
|
+
datacenter_token_rings[host.datacenter] ||= Hash.new
|
|
38
|
+
datacenter_token_rings[host.datacenter][i] = token
|
|
32
39
|
end
|
|
33
40
|
|
|
34
41
|
replication_map = ::Hash.new
|
|
35
42
|
|
|
36
43
|
token_ring.each_with_index do |token, i|
|
|
37
|
-
all_replicas = ::Hash.new
|
|
38
|
-
visited = ::Hash.new
|
|
39
|
-
skipped_datacenter_hosts = ::Hash.new
|
|
40
44
|
replicas = ::Set.new
|
|
45
|
+
visited = ::Hash.new
|
|
46
|
+
skipped = ::Hash.new
|
|
41
47
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
datacenter = host.datacenter
|
|
47
|
-
next if datacenter.nil?
|
|
48
|
+
replication_options.each do |datacenter, factor|
|
|
49
|
+
ring = datacenter_token_rings[datacenter]
|
|
50
|
+
next unless ring
|
|
51
|
+
factor = [Integer(factor), ring.size].min rescue next
|
|
48
52
|
|
|
49
|
-
factor = replication_options[datacenter]
|
|
50
|
-
next unless factor
|
|
51
53
|
|
|
52
|
-
|
|
54
|
+
total_racks = racks[datacenter].size
|
|
55
|
+
visited_racks = visited[datacenter] ||= ::Set.new
|
|
56
|
+
skipped_hosts = skipped[datacenter] ||= ::Set.new
|
|
57
|
+
added_replicas = ::Set.new
|
|
53
58
|
|
|
54
|
-
|
|
55
|
-
|
|
59
|
+
size.times do |j|
|
|
60
|
+
break if added_replicas.size >= factor
|
|
56
61
|
|
|
57
|
-
|
|
58
|
-
|
|
62
|
+
tk = ring[(i + j) % size]
|
|
63
|
+
next unless tk
|
|
64
|
+
host = token_hosts[tk]
|
|
65
|
+
rack = host.rack
|
|
59
66
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
replicas_in_datacenter << host
|
|
63
|
-
else
|
|
64
|
-
if visited_racks.include?(rack)
|
|
65
|
-
skipped_hosts = skipped_datacenter_hosts[datacenter] ||= ::Set.new
|
|
66
|
-
skipped_hosts << host
|
|
67
|
-
else
|
|
67
|
+
# unknown rack or seen all racks
|
|
68
|
+
if rack.nil? || visited_racks.size == total_racks
|
|
68
69
|
replicas << host
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
70
|
+
added_replicas << host
|
|
71
|
+
else
|
|
72
|
+
if visited_racks.include?(rack)
|
|
73
|
+
skipped_hosts << host
|
|
74
|
+
else
|
|
75
|
+
replicas << host
|
|
76
|
+
visited_racks << rack
|
|
77
|
+
added_replicas << host
|
|
78
|
+
|
|
79
|
+
if visited_racks.size == total_racks
|
|
80
|
+
skipped_hosts.each do |skipped_host|
|
|
81
|
+
break if added_replicas.size >= factor
|
|
82
|
+
|
|
83
|
+
replicas << skipped_host
|
|
84
|
+
added_replicas << host
|
|
85
|
+
end
|
|
77
86
|
end
|
|
78
87
|
end
|
|
79
88
|
end
|
|
@@ -108,7 +108,7 @@ module Cassandra
|
|
|
108
108
|
return lookup_type(node.children.first)
|
|
109
109
|
end
|
|
110
110
|
|
|
111
|
-
type = @@types
|
|
111
|
+
type = @@types.fetch(node.name) { return Cassandra::Types.custom(dump_node(node)) }
|
|
112
112
|
|
|
113
113
|
case type
|
|
114
114
|
when :set, :list
|
|
@@ -159,6 +159,12 @@ module Cassandra
|
|
|
159
159
|
|
|
160
160
|
root
|
|
161
161
|
end
|
|
162
|
+
|
|
163
|
+
def dump_node(node)
|
|
164
|
+
str = node.name
|
|
165
|
+
str << '(' + node.children.map {|n| dump_node(n)}.join(',') + ')' unless node.children.empty?
|
|
166
|
+
str
|
|
167
|
+
end
|
|
162
168
|
end
|
|
163
169
|
end
|
|
164
170
|
end
|
|
@@ -16,12 +16,6 @@
|
|
|
16
16
|
# limitations under the License.
|
|
17
17
|
#++
|
|
18
18
|
|
|
19
|
-
begin
|
|
20
|
-
require 'lz4-ruby'
|
|
21
|
-
rescue LoadError => e
|
|
22
|
-
raise LoadError, %[LZ4 support requires the "lz4-ruby" gem: #{e.message}], e.backtrace
|
|
23
|
-
end
|
|
24
|
-
|
|
25
19
|
module Cassandra
|
|
26
20
|
module Compression
|
|
27
21
|
module Compressors
|
|
@@ -40,6 +34,14 @@ module Cassandra
|
|
|
40
34
|
# @param [Integer] min_size (64) Don't compress frames smaller than
|
|
41
35
|
# this size (see {#compress?}).
|
|
42
36
|
def initialize(min_size=64)
|
|
37
|
+
unless defined?(::LZ4::Raw)
|
|
38
|
+
begin
|
|
39
|
+
require 'lz4-ruby'
|
|
40
|
+
rescue LoadError => e
|
|
41
|
+
raise LoadError, %[LZ4 support requires the "lz4-ruby" gem: #{e.message}], e.backtrace
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
43
45
|
@algorithm = 'lz4'.freeze
|
|
44
46
|
@min_size = min_size
|
|
45
47
|
end
|
|
@@ -16,12 +16,6 @@
|
|
|
16
16
|
# limitations under the License.
|
|
17
17
|
#++
|
|
18
18
|
|
|
19
|
-
begin
|
|
20
|
-
require 'snappy'
|
|
21
|
-
rescue LoadError => e
|
|
22
|
-
raise LoadError, %[Snappy support requires the "snappy" gem: #{e.message}], e.backtrace
|
|
23
|
-
end
|
|
24
|
-
|
|
25
19
|
module Cassandra
|
|
26
20
|
module Compression
|
|
27
21
|
module Compressors
|
|
@@ -40,6 +34,14 @@ module Cassandra
|
|
|
40
34
|
# @param [Integer] min_size (64) Don't compress frames smaller than
|
|
41
35
|
# this size (see {#compress?}).
|
|
42
36
|
def initialize(min_size=64)
|
|
37
|
+
unless defined?(::Snappy)
|
|
38
|
+
begin
|
|
39
|
+
require 'snappy'
|
|
40
|
+
rescue LoadError => e
|
|
41
|
+
raise LoadError, %[Snappy support requires the "snappy" gem: #{e.message}], e.backtrace
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
43
45
|
@algorithm = 'snappy'.freeze
|
|
44
46
|
@min_size = min_size
|
|
45
47
|
end
|
data/lib/cassandra/driver.rb
CHANGED
|
@@ -86,7 +86,9 @@ module Cassandra
|
|
|
86
86
|
idle_timeout,
|
|
87
87
|
synchronize_schema,
|
|
88
88
|
schema_refresh_delay,
|
|
89
|
-
schema_refresh_timeout
|
|
89
|
+
schema_refresh_timeout,
|
|
90
|
+
client_timestamps,
|
|
91
|
+
nodelay
|
|
90
92
|
)
|
|
91
93
|
end
|
|
92
94
|
|
|
@@ -114,6 +116,8 @@ module Cassandra
|
|
|
114
116
|
let(:schema_refresh_timeout) { 10 }
|
|
115
117
|
let(:thread_pool_size) { 4 }
|
|
116
118
|
let(:shuffle_replicas) { true }
|
|
119
|
+
let(:client_timestamps) { false }
|
|
120
|
+
let(:nodelay) { false }
|
|
117
121
|
|
|
118
122
|
let(:connections_per_local_node) { 2 }
|
|
119
123
|
let(:connections_per_remote_node) { 1 }
|
|
@@ -143,7 +147,11 @@ module Cassandra
|
|
|
143
147
|
if f.resolved?
|
|
144
148
|
promise.fulfill(cluster)
|
|
145
149
|
else
|
|
146
|
-
f.on_failure
|
|
150
|
+
f.on_failure do |e|
|
|
151
|
+
cluster.close_async.on_complete do |_, _|
|
|
152
|
+
promise.break(e)
|
|
153
|
+
end
|
|
154
|
+
end
|
|
147
155
|
end
|
|
148
156
|
end
|
|
149
157
|
|
|
@@ -23,14 +23,21 @@ module Cassandra
|
|
|
23
23
|
UNLOGGED_TYPE = 1
|
|
24
24
|
COUNTER_TYPE = 2
|
|
25
25
|
|
|
26
|
-
attr_reader :type
|
|
26
|
+
attr_reader :type, :timestamp
|
|
27
27
|
attr_accessor :consistency, :retries
|
|
28
28
|
|
|
29
|
-
def initialize(type, consistency, trace=false)
|
|
29
|
+
def initialize(type, consistency, trace=false, serial_consistency = nil, timestamp = nil)
|
|
30
30
|
super(0x0D, trace)
|
|
31
31
|
@type = type
|
|
32
32
|
@parts = []
|
|
33
33
|
@consistency = consistency
|
|
34
|
+
@serial_consistency = serial_consistency
|
|
35
|
+
@timestamp = timestamp
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def clear
|
|
39
|
+
@parts.clear
|
|
40
|
+
nil
|
|
34
41
|
end
|
|
35
42
|
|
|
36
43
|
def add_query(cql, values, types)
|
|
@@ -54,9 +61,13 @@ module Cassandra
|
|
|
54
61
|
buffer.append_consistency(@consistency)
|
|
55
62
|
|
|
56
63
|
if protocol_version > 2
|
|
57
|
-
flags
|
|
64
|
+
flags = 0
|
|
65
|
+
flags |= 0x10 if @serial_consistency
|
|
66
|
+
flags |= 0x20 if @timestamp
|
|
58
67
|
|
|
59
68
|
buffer.append(flags.chr)
|
|
69
|
+
buffer.append_consistency(@serial_consistency) if @serial_consistency
|
|
70
|
+
buffer.append_timestamp(@timestamp) if @timestamp
|
|
60
71
|
end
|
|
61
72
|
|
|
62
73
|
buffer
|
|
@@ -19,10 +19,10 @@
|
|
|
19
19
|
module Cassandra
|
|
20
20
|
module Protocol
|
|
21
21
|
class ExecuteRequest < Request
|
|
22
|
-
attr_reader :metadata, :values, :request_metadata, :serial_consistency, :page_size, :paging_state
|
|
22
|
+
attr_reader :metadata, :values, :request_metadata, :serial_consistency, :page_size, :paging_state, :timestamp
|
|
23
23
|
attr_accessor :consistency, :retries, :id
|
|
24
24
|
|
|
25
|
-
def initialize(id, metadata, values, request_metadata, consistency, serial_consistency=nil, page_size=nil, paging_state=nil, trace=false)
|
|
25
|
+
def initialize(id, metadata, values, request_metadata, consistency, serial_consistency=nil, page_size=nil, paging_state=nil, trace=false, timestamp = nil)
|
|
26
26
|
raise ArgumentError, "Metadata for #{metadata.size} columns, but #{values.size} values given" if metadata.size != values.size
|
|
27
27
|
raise ArgumentError, %(No such consistency: #{consistency.inspect}) if consistency.nil? || !CONSISTENCIES.include?(consistency)
|
|
28
28
|
raise ArgumentError, %(No such consistency: #{serial_consistency.inspect}) unless serial_consistency.nil? || CONSISTENCIES.include?(serial_consistency)
|
|
@@ -36,6 +36,7 @@ module Cassandra
|
|
|
36
36
|
@serial_consistency = serial_consistency
|
|
37
37
|
@page_size = page_size
|
|
38
38
|
@paging_state = paging_state
|
|
39
|
+
@timestamp = timestamp
|
|
39
40
|
end
|
|
40
41
|
|
|
41
42
|
def write(buffer, protocol_version, encoder)
|
|
@@ -48,6 +49,9 @@ module Cassandra
|
|
|
48
49
|
flags |= 0x04 if @page_size
|
|
49
50
|
flags |= 0x08 if @paging_state
|
|
50
51
|
flags |= 0x10 if @serial_consistency
|
|
52
|
+
if protocol_version > 2
|
|
53
|
+
flags |= 0x20 if @timestamp
|
|
54
|
+
end
|
|
51
55
|
buffer.append(flags.chr)
|
|
52
56
|
if @values.size > 0
|
|
53
57
|
encoder.write_parameters(buffer, @values, @metadata)
|
|
@@ -55,6 +59,9 @@ module Cassandra
|
|
|
55
59
|
buffer.append_int(@page_size) if @page_size
|
|
56
60
|
buffer.append_bytes(@paging_state) if @paging_state
|
|
57
61
|
buffer.append_consistency(@serial_consistency) if @serial_consistency
|
|
62
|
+
if protocol_version > 2
|
|
63
|
+
buffer.append_timestamp(@timestamp) if @timestamp
|
|
64
|
+
end
|
|
58
65
|
else
|
|
59
66
|
encoder.write_parameters(buffer, @values, @metadata)
|
|
60
67
|
buffer.append_consistency(@consistency)
|
|
@@ -19,10 +19,10 @@
|
|
|
19
19
|
module Cassandra
|
|
20
20
|
module Protocol
|
|
21
21
|
class QueryRequest < Request
|
|
22
|
-
attr_reader :cql, :values, :type_hints, :serial_consistency, :page_size, :paging_state
|
|
22
|
+
attr_reader :cql, :values, :type_hints, :serial_consistency, :page_size, :paging_state, :timestamp
|
|
23
23
|
attr_accessor :consistency, :retries
|
|
24
24
|
|
|
25
|
-
def initialize(cql, values, type_hints, consistency, serial_consistency = nil, page_size = nil, paging_state = nil, trace = false, names = EMPTY_LIST)
|
|
25
|
+
def initialize(cql, values, type_hints, consistency, serial_consistency = nil, page_size = nil, paging_state = nil, trace = false, names = EMPTY_LIST, timestamp = nil)
|
|
26
26
|
super(7, trace)
|
|
27
27
|
@cql = cql
|
|
28
28
|
@values = values
|
|
@@ -32,6 +32,7 @@ module Cassandra
|
|
|
32
32
|
@page_size = page_size
|
|
33
33
|
@paging_state = paging_state
|
|
34
34
|
@names = names
|
|
35
|
+
@timestamp = timestamp
|
|
35
36
|
end
|
|
36
37
|
|
|
37
38
|
def write(buffer, protocol_version, encoder)
|
|
@@ -42,9 +43,14 @@ module Cassandra
|
|
|
42
43
|
flags |= 0x04 if @page_size
|
|
43
44
|
flags |= 0x08 if @paging_state
|
|
44
45
|
flags |= 0x10 if @serial_consistency
|
|
46
|
+
if protocol_version > 2
|
|
47
|
+
flags |= 0x20 if @timestamp
|
|
48
|
+
end
|
|
45
49
|
if @values && @values.size > 0
|
|
46
50
|
flags |= 0x01
|
|
47
|
-
|
|
51
|
+
if protocol_version > 2
|
|
52
|
+
flags |= 0x40 unless @names.empty?
|
|
53
|
+
end
|
|
48
54
|
buffer.append(flags.chr)
|
|
49
55
|
encoder.write_parameters(buffer, @values, @type_hints, @names)
|
|
50
56
|
else
|
|
@@ -53,6 +59,9 @@ module Cassandra
|
|
|
53
59
|
buffer.append_int(@page_size) if @page_size
|
|
54
60
|
buffer.append_bytes(@paging_state) if @paging_state
|
|
55
61
|
buffer.append_consistency(@serial_consistency) if @serial_consistency
|
|
62
|
+
if protocol_version > 2
|
|
63
|
+
buffer.append_timestamp(@timestamp) if @timestamp
|
|
64
|
+
end
|
|
56
65
|
end
|
|
57
66
|
buffer
|
|
58
67
|
end
|
data/lib/cassandra/types.rb
CHANGED
|
@@ -1199,8 +1199,13 @@ module Cassandra
|
|
|
1199
1199
|
|
|
1200
1200
|
# @return [String] a cassandra representation of this type
|
|
1201
1201
|
def to_s
|
|
1202
|
-
"
|
|
1202
|
+
"'#{@name}'"
|
|
1203
1203
|
end
|
|
1204
|
+
|
|
1205
|
+
def eql?(other)
|
|
1206
|
+
other.is_a?(Custom) && @name == other.name
|
|
1207
|
+
end
|
|
1208
|
+
alias :== :eql?
|
|
1204
1209
|
end
|
|
1205
1210
|
|
|
1206
1211
|
# @return [Cassandra::Types::Varchar] varchar type
|
data/lib/cassandra/version.rb
CHANGED
data/lib/cassandra_murmur3.jar
CHANGED
|
Binary file
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
#--
|
|
4
|
+
# Copyright 2013-2015 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 DataStax
|
|
20
|
+
@base = __FILE__ + '/../..'
|
|
21
|
+
|
|
22
|
+
def self.require(path)
|
|
23
|
+
if path.start_with?('cassandra/')
|
|
24
|
+
include(path)
|
|
25
|
+
else
|
|
26
|
+
::Kernel.require(path)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.include(path)
|
|
31
|
+
path = File.expand_path(path + '.rb', @base)
|
|
32
|
+
class_eval(File.read(path), path, 1)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
previous = nil
|
|
36
|
+
if defined?(::Cassandra)
|
|
37
|
+
previous = ::Cassandra
|
|
38
|
+
Object.send(:remove_const, :Cassandra)
|
|
39
|
+
end
|
|
40
|
+
include 'cassandra'
|
|
41
|
+
DataStax::Cassandra::Murmur3 = ::Cassandra::Murmur3
|
|
42
|
+
Object.send(:remove_const, :Cassandra)
|
|
43
|
+
::Cassandra = previous if previous
|
|
44
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cassandra-driver
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.1.
|
|
4
|
+
version: 2.1.4
|
|
5
5
|
platform: java
|
|
6
6
|
authors:
|
|
7
7
|
- Theo Hultberg
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date: 2015-
|
|
12
|
+
date: 2015-07-01 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: ione
|
|
@@ -180,6 +180,7 @@ files:
|
|
|
180
180
|
- lib/cassandra/uuid/generator.rb
|
|
181
181
|
- lib/cassandra/version.rb
|
|
182
182
|
- lib/cassandra_murmur3.jar
|
|
183
|
+
- lib/datastax/cassandra.rb
|
|
183
184
|
homepage: http://datastax.github.io/ruby-driver
|
|
184
185
|
licenses:
|
|
185
186
|
- Apache License 2.0
|