cassandra-driver 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|