cassandra-driver 1.0.0 → 1.1.0
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 +8 -8
- data/README.md +23 -18
- data/lib/cassandra.rb +65 -26
- data/lib/cassandra/auth.rb +3 -3
- data/lib/cassandra/cluster.rb +63 -40
- data/lib/cassandra/cluster/client.rb +51 -24
- data/lib/cassandra/cluster/connection_pool.rb +6 -0
- data/lib/cassandra/cluster/control_connection.rb +155 -90
- data/lib/cassandra/cluster/options.rb +18 -11
- data/lib/cassandra/cluster/schema.rb +22 -1
- data/lib/cassandra/driver.rb +43 -9
- data/lib/cassandra/execution/options.rb +30 -3
- data/lib/cassandra/executors.rb +111 -0
- data/lib/cassandra/future.rb +88 -68
- data/lib/cassandra/keyspace.rb +7 -0
- data/lib/cassandra/load_balancing.rb +10 -0
- data/lib/cassandra/load_balancing/policies/dc_aware_round_robin.rb +3 -3
- data/lib/cassandra/load_balancing/policies/round_robin.rb +7 -5
- data/lib/cassandra/load_balancing/policies/token_aware.rb +28 -5
- data/lib/cassandra/load_balancing/policies/white_list.rb +1 -1
- data/lib/cassandra/protocol/cql_protocol_handler.rb +4 -1
- data/lib/cassandra/result.rb +30 -3
- data/lib/cassandra/session.rb +3 -0
- data/lib/cassandra/version.rb +1 -1
- metadata +3 -2
@@ -140,7 +140,7 @@ module Cassandra
|
|
140
140
|
end
|
141
141
|
|
142
142
|
def host_down(host)
|
143
|
-
|
143
|
+
pool = nil
|
144
144
|
|
145
145
|
synchronize do
|
146
146
|
return Ione::Future.resolved if !@connections.has_key?(host) && !@connecting_hosts.include?(host)
|
@@ -149,11 +149,11 @@ module Cassandra
|
|
149
149
|
@prepared_statements.delete(host)
|
150
150
|
@preparing_statements.delete(host)
|
151
151
|
|
152
|
-
|
152
|
+
pool = @connections.delete(host)
|
153
153
|
end
|
154
154
|
|
155
|
-
if
|
156
|
-
Ione::Future.all(*
|
155
|
+
if pool
|
156
|
+
Ione::Future.all(*pool.snapshot.map! {|c| c.close}).map(nil)
|
157
157
|
else
|
158
158
|
Ione::Future.resolved
|
159
159
|
end
|
@@ -171,8 +171,8 @@ module Cassandra
|
|
171
171
|
end
|
172
172
|
|
173
173
|
|
174
|
-
def query(statement, options
|
175
|
-
request = Protocol::QueryRequest.new(statement.cql, statement.params, nil, options.consistency, options.serial_consistency, options.page_size, paging_state, options.trace?)
|
174
|
+
def query(statement, options)
|
175
|
+
request = Protocol::QueryRequest.new(statement.cql, statement.params, nil, options.consistency, options.serial_consistency, options.page_size, options.paging_state, options.trace?)
|
176
176
|
timeout = options.timeout
|
177
177
|
promise = @futures.promise
|
178
178
|
|
@@ -198,10 +198,10 @@ module Cassandra
|
|
198
198
|
promise.future
|
199
199
|
end
|
200
200
|
|
201
|
-
def execute(statement, options
|
201
|
+
def execute(statement, options)
|
202
202
|
timeout = options.timeout
|
203
203
|
result_metadata = statement.result_metadata
|
204
|
-
request = Protocol::ExecuteRequest.new(nil, statement.params_metadata, statement.params, result_metadata.nil?, options.consistency, options.serial_consistency, options.page_size, paging_state, options.trace?)
|
204
|
+
request = Protocol::ExecuteRequest.new(nil, statement.params_metadata, statement.params, result_metadata.nil?, options.consistency, options.serial_consistency, options.page_size, options.paging_state, options.trace?)
|
205
205
|
promise = @futures.promise
|
206
206
|
|
207
207
|
keyspace = @keyspace
|
@@ -345,19 +345,46 @@ module Cassandra
|
|
345
345
|
return NO_CONNECTIONS
|
346
346
|
end
|
347
347
|
|
348
|
-
|
348
|
+
pool = nil
|
349
|
+
existing_connections = 0
|
350
|
+
|
351
|
+
synchronize do
|
352
|
+
pool = @connections[host]
|
353
|
+
end
|
354
|
+
|
355
|
+
existing_connections = pool.size if pool
|
356
|
+
pool = nil
|
357
|
+
missing_connections = (pool_size - existing_connections)
|
358
|
+
return Ione::Future.resolved if missing_connections <= 0
|
359
|
+
|
360
|
+
f = @connector.connect_many(host, missing_connections)
|
349
361
|
|
350
362
|
f.on_value do |connections|
|
351
|
-
|
363
|
+
pool = nil
|
352
364
|
|
353
365
|
synchronize do
|
354
366
|
@connecting_hosts.delete(host)
|
355
367
|
@prepared_statements[host] = {}
|
356
368
|
@preparing_statements[host] = {}
|
357
|
-
|
369
|
+
pool = @connections[host] ||= ConnectionPool.new
|
358
370
|
end
|
359
371
|
|
360
|
-
|
372
|
+
pool.add_connections(connections)
|
373
|
+
|
374
|
+
connections.each do |connection|
|
375
|
+
connection.on_closed do
|
376
|
+
distance = nil
|
377
|
+
|
378
|
+
synchronize do
|
379
|
+
if !(@state == :closed || @state == :closing) && !@connecting_hosts.include?(host) && @connections.include?(host)
|
380
|
+
distance = @load_balancing_policy.distance(host)
|
381
|
+
@connecting_hosts[host] = distance unless distance == :ignore
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
connect_to_host_maybe_retry(host, distance).map(nil) if distance
|
386
|
+
end
|
387
|
+
end
|
361
388
|
end
|
362
389
|
|
363
390
|
f
|
@@ -370,16 +397,16 @@ module Cassandra
|
|
370
397
|
end
|
371
398
|
|
372
399
|
hosts << host = plan.next
|
373
|
-
|
374
|
-
synchronize {
|
400
|
+
pool = nil
|
401
|
+
synchronize { pool = @connections[host] }
|
375
402
|
|
376
|
-
unless
|
403
|
+
unless pool
|
377
404
|
errors ||= {}
|
378
405
|
errors[host] = NOT_CONNECTED
|
379
406
|
return execute_by_plan(promise, keyspace, statement, options, request, plan, timeout, errors, hosts)
|
380
407
|
end
|
381
408
|
|
382
|
-
connection =
|
409
|
+
connection = pool.random_connection
|
383
410
|
|
384
411
|
if keyspace && connection.keyspace != keyspace
|
385
412
|
switch = switch_keyspace(connection, keyspace, timeout)
|
@@ -444,16 +471,16 @@ module Cassandra
|
|
444
471
|
end
|
445
472
|
|
446
473
|
hosts << host = plan.next
|
447
|
-
|
448
|
-
synchronize {
|
474
|
+
pool = nil
|
475
|
+
synchronize { pool = @connections[host] }
|
449
476
|
|
450
|
-
unless
|
477
|
+
unless pool
|
451
478
|
errors ||= {}
|
452
479
|
errors[host] = NOT_CONNECTED
|
453
480
|
return batch_by_plan(promise, keyspace, statement, options, plan, timeout, errors, hosts)
|
454
481
|
end
|
455
482
|
|
456
|
-
connection =
|
483
|
+
connection = pool.random_connection
|
457
484
|
|
458
485
|
if keyspace && connection.keyspace != keyspace
|
459
486
|
switch = switch_keyspace(connection, keyspace, timeout)
|
@@ -543,16 +570,16 @@ module Cassandra
|
|
543
570
|
end
|
544
571
|
|
545
572
|
hosts << host = plan.next
|
546
|
-
|
547
|
-
synchronize {
|
573
|
+
pool = nil
|
574
|
+
synchronize { pool = @connections[host] }
|
548
575
|
|
549
|
-
unless
|
576
|
+
unless pool
|
550
577
|
errors ||= {}
|
551
578
|
errors[host] = NOT_CONNECTED
|
552
579
|
return send_request_by_plan(promise, keyspace, statement, options, request, plan, timeout, errors, hosts)
|
553
580
|
end
|
554
581
|
|
555
|
-
connection =
|
582
|
+
connection = pool.random_connection
|
556
583
|
|
557
584
|
if keyspace && connection.keyspace != keyspace
|
558
585
|
switch = switch_keyspace(connection, keyspace, timeout)
|
@@ -22,7 +22,7 @@ module Cassandra
|
|
22
22
|
class ControlConnection
|
23
23
|
include MonitorMixin
|
24
24
|
|
25
|
-
def initialize(logger, io_reactor, cluster_registry, cluster_schema, cluster_metadata, load_balancing_policy, reconnection_policy, address_resolution_policy, connector)
|
25
|
+
def initialize(logger, io_reactor, cluster_registry, cluster_schema, cluster_metadata, load_balancing_policy, reconnection_policy, address_resolution_policy, connector, connection_options)
|
26
26
|
@logger = logger
|
27
27
|
@io_reactor = io_reactor
|
28
28
|
@registry = cluster_registry
|
@@ -32,17 +32,24 @@ module Cassandra
|
|
32
32
|
@reconnection_policy = reconnection_policy
|
33
33
|
@address_resolver = address_resolution_policy
|
34
34
|
@connector = connector
|
35
|
-
@
|
35
|
+
@connection_options = connection_options
|
36
|
+
@refreshing_statuses = ::Hash.new(false)
|
36
37
|
@status = :closed
|
37
|
-
@refreshing_schema = false
|
38
|
-
@refreshing_keyspaces = Hash.new(false)
|
39
|
-
@refreshing_tables = Hash.new
|
40
38
|
@refreshing_hosts = false
|
41
|
-
@refreshing_host = Hash.new(false)
|
39
|
+
@refreshing_host = ::Hash.new(false)
|
40
|
+
@closed_promise = Ione::Promise.new
|
41
|
+
@schema_changes = ::Array.new
|
42
|
+
@schema_refresh_timer = nil
|
43
|
+
@schema_refresh_window = nil
|
42
44
|
|
43
45
|
mon_initialize
|
44
46
|
end
|
45
47
|
|
48
|
+
def on_close(&block)
|
49
|
+
@closed_promise.future.on_value(&block)
|
50
|
+
@closed_promise.future.on_failure(&block)
|
51
|
+
end
|
52
|
+
|
46
53
|
def connect_async
|
47
54
|
synchronize do
|
48
55
|
return Ione::Future.resolved if @status == :connecting || @status == :connected
|
@@ -110,10 +117,33 @@ module Cassandra
|
|
110
117
|
|
111
118
|
def close_async
|
112
119
|
synchronize do
|
113
|
-
return
|
120
|
+
return @closed_promise.future if @status == :closing || @status == :closed
|
114
121
|
@status = :closing
|
115
122
|
end
|
116
|
-
@io_reactor.stop
|
123
|
+
f = @io_reactor.stop
|
124
|
+
|
125
|
+
f.on_value(&method(:connection_closed))
|
126
|
+
f.on_failure(&method(:connection_closed))
|
127
|
+
|
128
|
+
@closed_promise.future
|
129
|
+
end
|
130
|
+
|
131
|
+
def connection_closed(cause)
|
132
|
+
@closed_promise.fulfill
|
133
|
+
end
|
134
|
+
|
135
|
+
def refresh_schema_async_maybe_retry
|
136
|
+
refresh_schema_async.fallback do |e|
|
137
|
+
case e
|
138
|
+
when Errors::HostError
|
139
|
+
refresh_schema_async_retry(e, @reconnection_policy.schedule)
|
140
|
+
else
|
141
|
+
connection = @connection
|
142
|
+
connection && connection.close(e)
|
143
|
+
|
144
|
+
Ione::Future.failed(e)
|
145
|
+
end
|
146
|
+
end
|
117
147
|
end
|
118
148
|
|
119
149
|
def inspect
|
@@ -127,11 +157,6 @@ module Cassandra
|
|
127
157
|
SELECT_KEYSPACES = Protocol::QueryRequest.new('SELECT * FROM system.schema_keyspaces', nil, nil, :one)
|
128
158
|
SELECT_TABLES = Protocol::QueryRequest.new('SELECT * FROM system.schema_columnfamilies', nil, nil, :one)
|
129
159
|
SELECT_COLUMNS = Protocol::QueryRequest.new('SELECT * FROM system.schema_columns', nil, nil, :one)
|
130
|
-
REGISTER = Protocol::RegisterRequest.new(
|
131
|
-
Protocol::TopologyChangeEventResponse::TYPE,
|
132
|
-
Protocol::StatusChangeEventResponse::TYPE,
|
133
|
-
Protocol::SchemaChangeEventResponse::TYPE
|
134
|
-
)
|
135
160
|
|
136
161
|
def reconnect_async(schedule)
|
137
162
|
timeout = schedule.next
|
@@ -163,7 +188,14 @@ module Cassandra
|
|
163
188
|
|
164
189
|
return Ione::Future.failed(Errors::ClientError.new('Not connected')) if connection.nil?
|
165
190
|
|
166
|
-
|
191
|
+
request = Protocol::RegisterRequest.new(
|
192
|
+
Protocol::TopologyChangeEventResponse::TYPE,
|
193
|
+
Protocol::StatusChangeEventResponse::TYPE
|
194
|
+
)
|
195
|
+
|
196
|
+
request.events << Protocol::SchemaChangeEventResponse::TYPE if @connection_options.synchronize_schema?
|
197
|
+
|
198
|
+
f = connection.send_request(request)
|
167
199
|
f = f.map do |r|
|
168
200
|
case r
|
169
201
|
when Protocol::ReadyResponse
|
@@ -179,26 +211,7 @@ module Cassandra
|
|
179
211
|
@logger.debug("Event received #{event}")
|
180
212
|
|
181
213
|
if event.type == 'SCHEMA_CHANGE'
|
182
|
-
|
183
|
-
when 'CREATED'
|
184
|
-
if event.table.empty?
|
185
|
-
refresh_schema_async_maybe_retry
|
186
|
-
else
|
187
|
-
refresh_keyspace_async_maybe_retry(event.keyspace)
|
188
|
-
end
|
189
|
-
when 'DROPPED'
|
190
|
-
if event.table.empty?
|
191
|
-
refresh_schema_async_maybe_retry
|
192
|
-
else
|
193
|
-
refresh_keyspace_async_maybe_retry(event.keyspace)
|
194
|
-
end
|
195
|
-
when 'UPDATED'
|
196
|
-
if event.table.empty?
|
197
|
-
refresh_keyspace_async_maybe_retry(event.keyspace)
|
198
|
-
else
|
199
|
-
refresh_table_async_maybe_retry(event.keyspace, event.table)
|
200
|
-
end
|
201
|
-
end
|
214
|
+
handle_schema_change(event)
|
202
215
|
else
|
203
216
|
case event.change
|
204
217
|
when 'UP'
|
@@ -242,29 +255,6 @@ module Cassandra
|
|
242
255
|
end
|
243
256
|
end
|
244
257
|
|
245
|
-
def refresh_schema_async_maybe_retry
|
246
|
-
synchronize do
|
247
|
-
return Ione::Future.resolved if @refreshing_schema
|
248
|
-
@refreshing_schema = true
|
249
|
-
end
|
250
|
-
|
251
|
-
refresh_schema_async.fallback do |e|
|
252
|
-
case e
|
253
|
-
when Errors::HostError
|
254
|
-
refresh_schema_async_retry(e, @reconnection_policy.schedule)
|
255
|
-
else
|
256
|
-
connection = @connection
|
257
|
-
connection && connection.close(e)
|
258
|
-
|
259
|
-
Ione::Future.resolved
|
260
|
-
end
|
261
|
-
end.map do
|
262
|
-
synchronize do
|
263
|
-
@refreshing_schema = false
|
264
|
-
end
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
258
|
def refresh_schema_async_retry(error, schedule)
|
269
259
|
timeout = schedule.next
|
270
260
|
@logger.info("Failed to refresh schema (#{error.class.name}: #{error.message}), retrying in #{timeout}")
|
@@ -279,18 +269,13 @@ module Cassandra
|
|
279
269
|
connection = @connection
|
280
270
|
connection && connection.close(e)
|
281
271
|
|
282
|
-
Ione::Future.
|
272
|
+
Ione::Future.failed(e)
|
283
273
|
end
|
284
274
|
end
|
285
275
|
end
|
286
276
|
end
|
287
277
|
|
288
278
|
def refresh_keyspace_async_maybe_retry(keyspace)
|
289
|
-
synchronize do
|
290
|
-
return Ione::Future.resolved if @refreshing_schema || @refreshing_keyspaces[keyspace]
|
291
|
-
@refreshing_keyspaces[keyspace] = true
|
292
|
-
end
|
293
|
-
|
294
279
|
refresh_keyspace_async(keyspace).fallback do |e|
|
295
280
|
case e
|
296
281
|
when Errors::HostError
|
@@ -299,11 +284,7 @@ module Cassandra
|
|
299
284
|
connection = @connection
|
300
285
|
connection && connection.close(e)
|
301
286
|
|
302
|
-
Ione::Future.
|
303
|
-
end
|
304
|
-
end.map do
|
305
|
-
synchronize do
|
306
|
-
@refreshing_keyspaces.delete(host)
|
287
|
+
Ione::Future.failed(e)
|
307
288
|
end
|
308
289
|
end
|
309
290
|
end
|
@@ -322,7 +303,7 @@ module Cassandra
|
|
322
303
|
connection = @connection
|
323
304
|
connection && connection.close(e)
|
324
305
|
|
325
|
-
Ione::Future.
|
306
|
+
Ione::Future.failed(e)
|
326
307
|
end
|
327
308
|
end
|
328
309
|
end
|
@@ -340,17 +321,15 @@ module Cassandra
|
|
340
321
|
Ione::Future.all(keyspaces, tables, columns).map do |(keyspaces, tables, columns)|
|
341
322
|
host = @registry.host(connection.host)
|
342
323
|
|
343
|
-
|
324
|
+
if keyspaces.empty?
|
325
|
+
@schema.delete_keyspace(keyspace)
|
326
|
+
else
|
327
|
+
@schema.update_keyspace(host, keyspaces.first, tables, columns)
|
328
|
+
end
|
344
329
|
end
|
345
330
|
end
|
346
331
|
|
347
332
|
def refresh_table_async_maybe_retry(keyspace, table)
|
348
|
-
synchronize do
|
349
|
-
return Ione::Future.resolved if @refreshing_schema || @refreshing_keyspaces[keyspace] || @refreshing_tables[keyspace][table]
|
350
|
-
@refreshing_tables[keyspace] ||= ::Hash.new(false)
|
351
|
-
@refreshing_tables[keyspace][table] = true
|
352
|
-
end
|
353
|
-
|
354
333
|
refresh_table_async(keyspace, table).fallback do |e|
|
355
334
|
case e
|
356
335
|
when Errors::HostError
|
@@ -359,12 +338,7 @@ module Cassandra
|
|
359
338
|
connection = @connection
|
360
339
|
connection && connection.close(e)
|
361
340
|
|
362
|
-
Ione::Future.
|
363
|
-
end
|
364
|
-
end.map do
|
365
|
-
synchronize do
|
366
|
-
@refreshing_tables[keyspace].delete(table)
|
367
|
-
@refreshing_tables.delete(keyspace) if @refreshing_tables[keyspace].empty?
|
341
|
+
Ione::Future.failed(e)
|
368
342
|
end
|
369
343
|
end
|
370
344
|
end
|
@@ -383,7 +357,7 @@ module Cassandra
|
|
383
357
|
connection = @connection
|
384
358
|
connection && connection.close(e)
|
385
359
|
|
386
|
-
Ione::Future.
|
360
|
+
Ione::Future.failed(e)
|
387
361
|
end
|
388
362
|
end
|
389
363
|
end
|
@@ -395,13 +369,17 @@ module Cassandra
|
|
395
369
|
return Ione::Future.failed(Errors::ClientError.new('Not connected')) if connection.nil?
|
396
370
|
|
397
371
|
params = [keyspace, table]
|
398
|
-
|
372
|
+
tables = send_select_request(connection, Protocol::QueryRequest.new("SELECT * FROM system.schema_columnfamilies WHERE keyspace_name = '%s' AND columnfamily_name = '%s'" % params, nil, nil, :one))
|
399
373
|
columns = send_select_request(connection, Protocol::QueryRequest.new("SELECT * FROM system.schema_columns WHERE keyspace_name = '%s' AND columnfamily_name = '%s'" % params, nil, nil, :one))
|
400
374
|
|
401
|
-
Ione::Future.all(
|
375
|
+
Ione::Future.all(tables, columns).map do |(tables, columns)|
|
402
376
|
host = @registry.host(connection.host)
|
403
377
|
|
404
|
-
|
378
|
+
if tables.empty?
|
379
|
+
@schema.delete_table(keyspace, table)
|
380
|
+
else
|
381
|
+
@schema.udpate_table(host, keyspace, tables.first, columns)
|
382
|
+
end
|
405
383
|
end
|
406
384
|
end
|
407
385
|
|
@@ -419,7 +397,7 @@ module Cassandra
|
|
419
397
|
connection = @connection
|
420
398
|
connection && connection.close(e)
|
421
399
|
|
422
|
-
Ione::Future.
|
400
|
+
Ione::Future.failed(e)
|
423
401
|
end
|
424
402
|
end.map do
|
425
403
|
synchronize do
|
@@ -442,7 +420,7 @@ module Cassandra
|
|
442
420
|
connection = @connection
|
443
421
|
connection && connection.close(e)
|
444
422
|
|
445
|
-
Ione::Future.
|
423
|
+
Ione::Future.failed(e)
|
446
424
|
end
|
447
425
|
end
|
448
426
|
end
|
@@ -468,6 +446,7 @@ module Cassandra
|
|
468
446
|
@metadata.update(data)
|
469
447
|
end
|
470
448
|
|
449
|
+
peers.shuffle!
|
471
450
|
peers.each do |data|
|
472
451
|
ip = peer_ip(data)
|
473
452
|
next unless ip
|
@@ -524,7 +503,7 @@ module Cassandra
|
|
524
503
|
connection = @connection
|
525
504
|
connection && connection.close(e)
|
526
505
|
|
527
|
-
Ione::Future.
|
506
|
+
Ione::Future.failed(e)
|
528
507
|
end
|
529
508
|
end.map do
|
530
509
|
synchronize do
|
@@ -547,7 +526,7 @@ module Cassandra
|
|
547
526
|
connection = @connection
|
548
527
|
connection && connection.close(e)
|
549
528
|
|
550
|
-
Ione::Future.
|
529
|
+
Ione::Future.failed(e)
|
551
530
|
end
|
552
531
|
end
|
553
532
|
end
|
@@ -661,6 +640,92 @@ Control connection failed and is unlikely to recover.
|
|
661
640
|
@address_resolver.resolve(ip)
|
662
641
|
end
|
663
642
|
|
643
|
+
def process_schema_changes(schema_changes)
|
644
|
+
refresh_keyspaces = ::Hash.new
|
645
|
+
refresh_tables = ::Hash.new
|
646
|
+
|
647
|
+
schema_changes.each do |change|
|
648
|
+
keyspace = change.keyspace
|
649
|
+
table = change.table
|
650
|
+
|
651
|
+
next if refresh_keyspaces.has_key?(keyspace)
|
652
|
+
|
653
|
+
if table.empty?
|
654
|
+
refresh_tables.delete(keyspace)
|
655
|
+
refresh_keyspaces[keyspace] = true
|
656
|
+
else
|
657
|
+
tables = refresh_tables[keyspace] ||= ::Hash.new
|
658
|
+
tables[table] = true
|
659
|
+
end
|
660
|
+
end
|
661
|
+
|
662
|
+
futures = ::Array.new
|
663
|
+
|
664
|
+
refresh_keyspaces.each do |(keyspace, _)|
|
665
|
+
futures << refresh_keyspace_async_maybe_retry(keyspace)
|
666
|
+
end
|
667
|
+
|
668
|
+
refresh_tables.each do |(keyspace, tables)|
|
669
|
+
tables.each do |(table, _)|
|
670
|
+
futures << refresh_table_async_maybe_retry(keyspace, table)
|
671
|
+
end
|
672
|
+
end
|
673
|
+
|
674
|
+
Ione::Future.all(*futures)
|
675
|
+
end
|
676
|
+
|
677
|
+
def handle_schema_change(change)
|
678
|
+
timer = nil
|
679
|
+
expiration_timer = nil
|
680
|
+
|
681
|
+
synchronize do
|
682
|
+
@schema_changes << change
|
683
|
+
|
684
|
+
@io_reactor.cancel_timer(@schema_refresh_timer) if @schema_refresh_timer
|
685
|
+
timer = @schema_refresh_timer = @io_reactor.schedule_timer(@connection_options.schema_refresh_delay)
|
686
|
+
|
687
|
+
unless @schema_refresh_window
|
688
|
+
expiration_timer = @schema_refresh_window = @io_reactor.schedule_timer(@connection_options.schema_refresh_timeout)
|
689
|
+
end
|
690
|
+
end
|
691
|
+
|
692
|
+
if expiration_timer
|
693
|
+
expiration_timer.on_value do
|
694
|
+
schema_changes = nil
|
695
|
+
|
696
|
+
synchronize do
|
697
|
+
@io_reactor.cancel_timer(@schema_refresh_timer)
|
698
|
+
|
699
|
+
@schema_refresh_window = nil
|
700
|
+
@schema_refresh_timer = nil
|
701
|
+
|
702
|
+
schema_changes = @schema_changes
|
703
|
+
@schema_changes = ::Array.new
|
704
|
+
end
|
705
|
+
|
706
|
+
process_schema_changes(schema_changes)
|
707
|
+
end
|
708
|
+
end
|
709
|
+
|
710
|
+
timer.on_value do
|
711
|
+
schema_changes = nil
|
712
|
+
|
713
|
+
synchronize do
|
714
|
+
@io_reactor.cancel_timer(@schema_refresh_window)
|
715
|
+
|
716
|
+
@schema_refresh_window = nil
|
717
|
+
@schema_refresh_timer = nil
|
718
|
+
|
719
|
+
schema_changes = @schema_changes
|
720
|
+
@schema_changes = ::Array.new
|
721
|
+
end
|
722
|
+
|
723
|
+
process_schema_changes(schema_changes)
|
724
|
+
end
|
725
|
+
|
726
|
+
nil
|
727
|
+
end
|
728
|
+
|
664
729
|
def send_select_request(connection, request)
|
665
730
|
connection.send_request(request).map do |r|
|
666
731
|
case r
|