cassandra-driver 3.0.0.beta.1-java → 3.0.0-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (138) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +106 -39
  3. data/lib/cassandra.rb +396 -148
  4. data/lib/cassandra/address_resolution.rb +1 -1
  5. data/lib/cassandra/address_resolution/policies/ec2_multi_region.rb +1 -1
  6. data/lib/cassandra/address_resolution/policies/none.rb +1 -1
  7. data/lib/cassandra/aggregate.rb +21 -7
  8. data/lib/cassandra/argument.rb +2 -2
  9. data/lib/cassandra/attr_boolean.rb +33 -0
  10. data/lib/cassandra/auth.rb +6 -5
  11. data/lib/cassandra/auth/providers.rb +1 -1
  12. data/lib/cassandra/auth/providers/password.rb +5 -13
  13. data/lib/cassandra/cassandra_logger.rb +80 -0
  14. data/lib/cassandra/cluster.rb +49 -9
  15. data/lib/cassandra/cluster/client.rb +835 -209
  16. data/lib/cassandra/cluster/connection_pool.rb +2 -2
  17. data/lib/cassandra/cluster/connector.rb +86 -27
  18. data/lib/cassandra/cluster/control_connection.rb +222 -95
  19. data/lib/cassandra/cluster/failed_connection.rb +1 -1
  20. data/lib/cassandra/cluster/metadata.rb +14 -8
  21. data/lib/cassandra/cluster/options.rb +68 -22
  22. data/lib/cassandra/cluster/registry.rb +81 -17
  23. data/lib/cassandra/cluster/schema.rb +70 -8
  24. data/lib/cassandra/cluster/schema/cql_type_parser.rb +15 -10
  25. data/lib/cassandra/cluster/schema/fetchers.rb +601 -241
  26. data/lib/cassandra/cluster/schema/fqcn_type_parser.rb +39 -38
  27. data/lib/cassandra/cluster/schema/partitioners.rb +1 -1
  28. data/lib/cassandra/cluster/schema/partitioners/murmur3.rb +6 -8
  29. data/lib/cassandra/cluster/schema/partitioners/ordered.rb +1 -1
  30. data/lib/cassandra/cluster/schema/partitioners/random.rb +1 -1
  31. data/lib/cassandra/cluster/schema/replication_strategies.rb +1 -1
  32. data/lib/cassandra/cluster/schema/replication_strategies/network_topology.rb +19 -18
  33. data/lib/cassandra/cluster/schema/replication_strategies/none.rb +1 -1
  34. data/lib/cassandra/cluster/schema/replication_strategies/simple.rb +1 -1
  35. data/lib/cassandra/column.rb +4 -23
  36. data/lib/cassandra/column_container.rb +322 -0
  37. data/lib/cassandra/compression.rb +1 -1
  38. data/lib/cassandra/compression/compressors/lz4.rb +7 -8
  39. data/lib/cassandra/compression/compressors/snappy.rb +4 -3
  40. data/lib/cassandra/driver.rb +107 -46
  41. data/lib/cassandra/errors.rb +303 -52
  42. data/lib/cassandra/execution/info.rb +16 -5
  43. data/lib/cassandra/execution/options.rb +102 -55
  44. data/lib/cassandra/execution/trace.rb +16 -9
  45. data/lib/cassandra/executors.rb +1 -1
  46. data/lib/cassandra/function.rb +19 -13
  47. data/lib/cassandra/function_collection.rb +85 -0
  48. data/lib/cassandra/future.rb +101 -49
  49. data/lib/cassandra/host.rb +25 -5
  50. data/lib/cassandra/index.rb +118 -0
  51. data/lib/cassandra/keyspace.rb +169 -33
  52. data/lib/cassandra/listener.rb +1 -1
  53. data/lib/cassandra/load_balancing.rb +2 -2
  54. data/lib/cassandra/load_balancing/policies.rb +1 -1
  55. data/lib/cassandra/load_balancing/policies/dc_aware_round_robin.rb +39 -25
  56. data/lib/cassandra/load_balancing/policies/round_robin.rb +8 -1
  57. data/lib/cassandra/load_balancing/policies/token_aware.rb +22 -13
  58. data/lib/cassandra/load_balancing/policies/white_list.rb +18 -5
  59. data/lib/cassandra/materialized_view.rb +90 -0
  60. data/lib/cassandra/null_logger.rb +27 -6
  61. data/lib/cassandra/protocol.rb +1 -1
  62. data/lib/cassandra/protocol/coder.rb +81 -42
  63. data/lib/cassandra/protocol/cql_byte_buffer.rb +58 -44
  64. data/lib/cassandra/protocol/cql_protocol_handler.rb +57 -54
  65. data/lib/cassandra/protocol/request.rb +6 -7
  66. data/lib/cassandra/protocol/requests/auth_response_request.rb +3 -3
  67. data/lib/cassandra/protocol/requests/batch_request.rb +17 -8
  68. data/lib/cassandra/protocol/requests/credentials_request.rb +3 -3
  69. data/lib/cassandra/protocol/requests/execute_request.rb +39 -20
  70. data/lib/cassandra/protocol/requests/options_request.rb +1 -1
  71. data/lib/cassandra/protocol/requests/prepare_request.rb +5 -5
  72. data/lib/cassandra/protocol/requests/query_request.rb +28 -23
  73. data/lib/cassandra/protocol/requests/register_request.rb +2 -2
  74. data/lib/cassandra/protocol/requests/startup_request.rb +8 -8
  75. data/lib/cassandra/protocol/requests/void_query_request.rb +1 -1
  76. data/lib/cassandra/protocol/response.rb +3 -4
  77. data/lib/cassandra/protocol/responses/already_exists_error_response.rb +12 -2
  78. data/lib/cassandra/protocol/responses/auth_challenge_response.rb +4 -5
  79. data/lib/cassandra/protocol/responses/auth_success_response.rb +4 -5
  80. data/lib/cassandra/protocol/responses/authenticate_response.rb +4 -5
  81. data/lib/cassandra/protocol/responses/error_response.rb +104 -17
  82. data/lib/cassandra/protocol/responses/event_response.rb +3 -4
  83. data/lib/cassandra/protocol/responses/function_failure_error_response.rb +13 -2
  84. data/lib/cassandra/protocol/responses/prepared_result_response.rb +14 -9
  85. data/lib/cassandra/protocol/responses/raw_rows_result_response.rb +14 -9
  86. data/lib/cassandra/protocol/responses/read_failure_error_response.rb +26 -4
  87. data/lib/cassandra/protocol/responses/read_timeout_error_response.rb +22 -3
  88. data/lib/cassandra/protocol/responses/ready_response.rb +6 -7
  89. data/lib/cassandra/protocol/responses/result_response.rb +11 -10
  90. data/lib/cassandra/protocol/responses/rows_result_response.rb +8 -7
  91. data/lib/cassandra/protocol/responses/schema_change_event_response.rb +8 -8
  92. data/lib/cassandra/protocol/responses/schema_change_result_response.rb +19 -13
  93. data/lib/cassandra/protocol/responses/set_keyspace_result_response.rb +5 -6
  94. data/lib/cassandra/protocol/responses/status_change_event_response.rb +5 -6
  95. data/lib/cassandra/protocol/responses/supported_response.rb +4 -5
  96. data/lib/cassandra/protocol/responses/topology_change_event_response.rb +4 -5
  97. data/lib/cassandra/protocol/responses/unavailable_error_response.rb +20 -3
  98. data/lib/cassandra/protocol/responses/unprepared_error_response.rb +11 -2
  99. data/lib/cassandra/protocol/responses/void_result_response.rb +4 -5
  100. data/lib/cassandra/protocol/responses/write_failure_error_response.rb +26 -4
  101. data/lib/cassandra/protocol/responses/write_timeout_error_response.rb +22 -3
  102. data/lib/cassandra/protocol/v1.rb +98 -37
  103. data/lib/cassandra/protocol/v3.rb +121 -50
  104. data/lib/cassandra/protocol/v4.rb +172 -68
  105. data/lib/cassandra/reconnection.rb +1 -1
  106. data/lib/cassandra/reconnection/policies.rb +1 -1
  107. data/lib/cassandra/reconnection/policies/constant.rb +2 -4
  108. data/lib/cassandra/reconnection/policies/exponential.rb +6 -6
  109. data/lib/cassandra/result.rb +55 -20
  110. data/lib/cassandra/retry.rb +8 -8
  111. data/lib/cassandra/retry/policies.rb +1 -1
  112. data/lib/cassandra/retry/policies/default.rb +1 -1
  113. data/lib/cassandra/retry/policies/downgrading_consistency.rb +4 -2
  114. data/lib/cassandra/retry/policies/fallthrough.rb +1 -1
  115. data/lib/cassandra/session.rb +24 -16
  116. data/lib/cassandra/statement.rb +1 -1
  117. data/lib/cassandra/statements.rb +1 -1
  118. data/lib/cassandra/statements/batch.rb +16 -10
  119. data/lib/cassandra/statements/bound.rb +10 -3
  120. data/lib/cassandra/statements/prepared.rb +62 -18
  121. data/lib/cassandra/statements/simple.rb +23 -10
  122. data/lib/cassandra/statements/void.rb +1 -1
  123. data/lib/cassandra/table.rb +53 -185
  124. data/lib/cassandra/time.rb +11 -6
  125. data/lib/cassandra/time_uuid.rb +12 -14
  126. data/lib/cassandra/timestamp_generator.rb +37 -0
  127. data/lib/cassandra/timestamp_generator/simple.rb +38 -0
  128. data/lib/cassandra/timestamp_generator/ticking_on_duplicate.rb +58 -0
  129. data/lib/cassandra/tuple.rb +4 -4
  130. data/lib/cassandra/types.rb +109 -71
  131. data/lib/cassandra/udt.rb +66 -50
  132. data/lib/cassandra/util.rb +155 -15
  133. data/lib/cassandra/uuid.rb +20 -21
  134. data/lib/cassandra/uuid/generator.rb +7 -5
  135. data/lib/cassandra/version.rb +2 -2
  136. data/lib/cassandra_murmur3.jar +0 -0
  137. data/lib/datastax/cassandra.rb +1 -1
  138. metadata +27 -16
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  #--
4
- # Copyright 2013-2015 DataStax, Inc.
4
+ # Copyright 2013-2016 DataStax, Inc.
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
7
7
  # you may not use this file except in compliance with the License.
@@ -19,8 +19,19 @@
19
19
  module Cassandra
20
20
  module Protocol
21
21
  class CqlByteBuffer < Ione::ByteBuffer
22
+ # @private
23
+ MINUS = '-'.freeze
24
+ # @private
25
+ ZERO = '0'.freeze
26
+ # @private
27
+ DECIMAL_POINT = '.'.freeze
28
+ # @private
29
+ FLOAT_STRING_FORMAT = 'F'.freeze
30
+ # @private
31
+ NO_CHAR = ''.freeze
32
+
22
33
  def inspect
23
- "#<#{self.class.name}:0x#{self.object_id.to_s(16)} #{to_str.inspect}>"
34
+ "#<#{self.class.name}:0x#{object_id.to_s(16)} #{to_str.inspect}>"
24
35
  end
25
36
 
26
37
  def read_unsigned_byte
@@ -28,22 +39,20 @@ module Cassandra
28
39
  rescue RangeError => e
29
40
  raise Errors::DecodingError, e.message, e.backtrace
30
41
  end
31
-
32
- def read_varint(len=bytesize, signed=true)
42
+
43
+ def read_varint(len = bytesize, signed = true)
33
44
  bytes = read(len)
34
45
  n = 0
35
46
  bytes.each_byte do |b|
36
47
  n = (n << 8) | b
37
48
  end
38
- if signed && bytes.getbyte(0) & 0x80 == 0x80
39
- n -= 2**(bytes.length * 8)
40
- end
49
+ n -= 2**(bytes.length * 8) if signed && bytes.getbyte(0) & 0x80 == 0x80
41
50
  n
42
51
  rescue RangeError => e
43
52
  raise Errors::DecodingError, e.message, e.backtrace
44
53
  end
45
54
 
46
- def read_decimal(len=bytesize)
55
+ def read_decimal(len = bytesize)
47
56
  size = read_signed_int
48
57
  number_string = read_varint(len - 4).to_s
49
58
  if number_string.length <= size
@@ -58,7 +67,8 @@ module Cassandra
58
67
  else
59
68
  fraction_string = number_string[0, number_string.length - size]
60
69
  fraction_string << DECIMAL_POINT
61
- fraction_string << number_string[number_string.length - size, number_string.length]
70
+ fraction_string <<
71
+ number_string[number_string.length - size, number_string.length]
62
72
  end
63
73
  BigDecimal.new(fraction_string)
64
74
  rescue Errors::DecodingError => e
@@ -78,13 +88,15 @@ module Cassandra
78
88
  def read_double
79
89
  read(8).unpack(Formats::DOUBLE_FORMAT).first
80
90
  rescue RangeError => e
81
- raise Errors::DecodingError, "Not enough bytes available to decode a double: #{e.message}", e.backtrace
91
+ raise Errors::DecodingError,
92
+ "Not enough bytes available to decode a double: #{e.message}", e.backtrace
82
93
  end
83
94
 
84
95
  def read_float
85
96
  read(4).unpack(Formats::FLOAT_FORMAT).first
86
97
  rescue RangeError => e
87
- raise Errors::DecodingError, "Not enough bytes available to decode a float: #{e.message}", e.backtrace
98
+ raise Errors::DecodingError,
99
+ "Not enough bytes available to decode a float: #{e.message}", e.backtrace
88
100
  end
89
101
 
90
102
  def read_signed_int
@@ -92,13 +104,15 @@ module Cassandra
92
104
  return n if n <= 0x7fffffff
93
105
  n - 0xffffffff - 1
94
106
  rescue RangeError => e
95
- raise Errors::DecodingError, "Not enough bytes available to decode an int: #{e.message}", e.backtrace
107
+ raise Errors::DecodingError,
108
+ "Not enough bytes available to decode an int: #{e.message}", e.backtrace
96
109
  end
97
-
110
+
98
111
  def read_unsigned_short
99
112
  read_short
100
113
  rescue RangeError => e
101
- raise Errors::DecodingError, "Not enough bytes available to decode a short: #{e.message}", e.backtrace
114
+ raise Errors::DecodingError,
115
+ "Not enough bytes available to decode a short: #{e.message}", e.backtrace
102
116
  end
103
117
 
104
118
  def read_string
@@ -107,7 +121,8 @@ module Cassandra
107
121
  string.force_encoding(::Encoding::UTF_8)
108
122
  string
109
123
  rescue RangeError => e
110
- raise Errors::DecodingError, "Not enough bytes available to decode a string: #{e.message}", e.backtrace
124
+ raise Errors::DecodingError,
125
+ "Not enough bytes available to decode a string: #{e.message}", e.backtrace
111
126
  end
112
127
 
113
128
  def read_long_string
@@ -116,13 +131,16 @@ module Cassandra
116
131
  string.force_encoding(::Encoding::UTF_8)
117
132
  string
118
133
  rescue RangeError => e
119
- raise Errors::DecodingError, "Not enough bytes available to decode a long string: #{e.message}", e.backtrace
134
+ raise Errors::DecodingError,
135
+ "Not enough bytes available to decode a long string: #{e.message}",
136
+ e.backtrace
120
137
  end
121
138
 
122
- def read_uuid(impl=Uuid)
139
+ def read_uuid(impl = Uuid)
123
140
  impl.new(read_varint(16, false))
124
141
  rescue Errors::DecodingError => e
125
- raise Errors::DecodingError, "Not enough bytes available to decode a UUID: #{e.message}", e.backtrace
142
+ raise Errors::DecodingError,
143
+ "Not enough bytes available to decode a UUID: #{e.message}", e.backtrace
126
144
  end
127
145
 
128
146
  def read_string_list
@@ -135,21 +153,22 @@ module Cassandra
135
153
  return nil if size & 0x80000000 == 0x80000000
136
154
  read(size)
137
155
  rescue RangeError => e
138
- raise Errors::DecodingError, "Not enough bytes available to decode a bytes: #{e.message}", e.backtrace
156
+ raise Errors::DecodingError,
157
+ "Not enough bytes available to decode a bytes: #{e.message}", e.backtrace
139
158
  end
140
159
 
141
160
  def read_short_bytes
142
161
  read(read_unsigned_short)
143
162
  rescue RangeError => e
144
- raise Errors::DecodingError, "Not enough bytes available to decode a short bytes: #{e.message}", e.backtrace
163
+ raise Errors::DecodingError,
164
+ "Not enough bytes available to decode a short bytes: #{e.message}",
165
+ e.backtrace
145
166
  end
146
167
 
147
168
  def read_option
148
169
  id = read_unsigned_short
149
170
  value = nil
150
- if block_given?
151
- value = yield id, self
152
- end
171
+ value = yield id, self if block_given?
153
172
  [id, value]
154
173
  end
155
174
 
@@ -159,12 +178,16 @@ module Cassandra
159
178
  port = read_int
160
179
  [ip_addr, port]
161
180
  rescue RangeError => e
162
- raise Errors::DecodingError, "Not enough bytes available to decode an INET: #{e.message}", e.backtrace
181
+ raise Errors::DecodingError,
182
+ "Not enough bytes available to decode an INET: #{e.message}",
183
+ e.backtrace
163
184
  end
164
185
 
165
186
  def read_consistency
166
187
  index = read_unsigned_short
167
- raise Errors::DecodingError, "Unknown consistency index #{index}" if index >= CONSISTENCIES.size || CONSISTENCIES[index].nil?
188
+ if index >= CONSISTENCIES.size || CONSISTENCIES[index].nil?
189
+ raise Errors::DecodingError, "Unknown consistency index #{index}"
190
+ end
168
191
  CONSISTENCIES[index]
169
192
  end
170
193
 
@@ -203,7 +226,8 @@ module Cassandra
203
226
  return n if n <= 0x7fff
204
227
  n - 0xffff - 1
205
228
  rescue RangeError => e
206
- raise Errors::DecodingError, "Not enough bytes available to decode a smallint: #{e.message}", e.backtrace
229
+ raise Errors::DecodingError,
230
+ "Not enough bytes available to decode a smallint: #{e.message}", e.backtrace
207
231
  end
208
232
 
209
233
  def read_tinyint
@@ -211,7 +235,8 @@ module Cassandra
211
235
  return n if n <= 0x7f
212
236
  n - 0xff - 1
213
237
  rescue RangeError => e
214
- raise Errors::DecodingError, "Not enough bytes available to decode a tinyint: #{e.message}", e.backtrace
238
+ raise Errors::DecodingError,
239
+ "Not enough bytes available to decode a tinyint: #{e.message}", e.backtrace
215
240
  end
216
241
 
217
242
  def append_tinyint(n)
@@ -246,7 +271,7 @@ module Cassandra
246
271
  append_int((v >> 96) & 0xffffffff)
247
272
  append_int((v >> 64) & 0xffffffff)
248
273
  append_int((v >> 32) & 0xffffffff)
249
- append_int((v >> 0) & 0xffffffff)
274
+ append_int((v >> 0) & 0xffffffff)
250
275
  end
251
276
 
252
277
  def append_string_list(strs)
@@ -299,10 +324,6 @@ module Cassandra
299
324
  self
300
325
  end
301
326
 
302
- def append_timestamp(timestamp)
303
- append_long(timestamp.tv_sec * 1000000 + timestamp.tv_usec)
304
- end
305
-
306
327
  def append_long(n)
307
328
  top = n >> 32
308
329
  bottom = n & 0xffffffff
@@ -313,10 +334,11 @@ module Cassandra
313
334
  def append_varint(n)
314
335
  num = n
315
336
  bytes = []
316
- begin
337
+ loop do
317
338
  bytes << (num & 0xff)
318
339
  num >>= 8
319
- end until (num == 0 || num == -1) && (bytes.last[7] == num[7])
340
+ break if (num == 0 || num == -1) && (bytes.last[7] == num[7])
341
+ end
320
342
  append(bytes.reverse.pack(Formats::BYTES_FORMAT))
321
343
  end
322
344
 
@@ -342,15 +364,7 @@ module Cassandra
342
364
  def eql?(other)
343
365
  other.eql?(to_str)
344
366
  end
345
- alias_method :==, :eql?
346
-
347
- private
348
-
349
- MINUS = '-'.freeze
350
- ZERO = '0'.freeze
351
- DECIMAL_POINT = '.'.freeze
352
- FLOAT_STRING_FORMAT = 'F'.freeze
353
- NO_CHAR = ''.freeze
367
+ alias == eql?
354
368
  end
355
369
  end
356
- end
370
+ end
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  #--
4
- # Copyright 2013-2015 DataStax, Inc.
4
+ # Copyright 2013-2016 DataStax, Inc.
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
7
7
  # you may not use this file except in compliance with the License.
@@ -32,22 +32,31 @@ module Cassandra
32
32
  # puts "These options are supported: #{response.options}"
33
33
  class CqlProtocolHandler
34
34
  # @return [String] the current keyspace for the underlying connection
35
- attr_reader :keyspace, :error
36
-
37
- def initialize(connection, scheduler, protocol_version, compressor=nil, heartbeat_interval = 30, idle_timeout = 60)
35
+ attr_reader :keyspace
36
+
37
+ # @return [Exception] outstanding error, from a failed connection.
38
+ attr_reader :error
39
+
40
+ # @return [Integer] the version of the protocol to use in communicating with C*.
41
+ attr_reader :protocol_version
42
+
43
+ def initialize(connection,
44
+ scheduler,
45
+ protocol_version,
46
+ compressor = nil,
47
+ heartbeat_interval = 30,
48
+ idle_timeout = 60,
49
+ requests_per_connection = 128)
50
+ @protocol_version = protocol_version
38
51
  @connection = connection
39
52
  @scheduler = scheduler
40
53
  @compressor = compressor
41
54
  @connection.on_data(&method(:receive_data))
42
55
  @connection.on_closed(&method(:socket_closed))
43
56
 
44
- if protocol_version > 2
45
- @streams = Array.new(1024) {|i| i}
46
- else
47
- @streams = Array.new(128) {|i| i}
48
- end
57
+ @streams = Array.new(requests_per_connection) {|i| i}
49
58
 
50
- @promises = Hash.new
59
+ @promises = {}
51
60
 
52
61
  if protocol_version > 3
53
62
  @frame_encoder = V4::Encoder.new(@compressor, protocol_version)
@@ -147,20 +156,20 @@ module Cassandra
147
156
  # closes the futures of all active requests will be failed with the error
148
157
  # that caused the connection to close, or nil.
149
158
  #
150
- # When `timeout` is specified the future will fail with {Cassandra::Errors::TimeoutError}
151
- # after that many seconds have passed. If a response arrives after that
152
- # time it will be lost. If a response never arrives for the request the
153
- # channel occupied by the request will _not_ be reused.
159
+ # When `timeout` is specified the future will fail with
160
+ # {Cassandra::Errors::TimeoutError} after that many seconds have passed. If a
161
+ # response arrives after that time it will be lost. If a response never arrives
162
+ # for the request the channel occupied by the request will _not_ be reused.
154
163
  #
155
164
  # @param [Cassandra::Protocol::Request] request
156
165
  # @param [Float] timeout an optional number of seconds to wait until
157
166
  # failing the request
158
167
  # @return [Ione::Future<Cassandra::Protocol::Response>] a future that resolves to
159
168
  # the response
160
- def send_request(request, timeout=nil, with_heartbeat = true)
169
+ def send_request(request, timeout = nil, with_heartbeat = true)
161
170
  return Ione::Future.failed(Errors::IOError.new('Connection closed')) if closed?
162
171
  schedule_heartbeat if with_heartbeat
163
- promise = RequestPromise.new(request)
172
+ promise = RequestPromise.new(request, timeout)
164
173
  id = nil
165
174
  @lock.lock
166
175
  begin
@@ -171,9 +180,7 @@ module Cassandra
171
180
  @lock.unlock
172
181
  end
173
182
  if id
174
- @connection.write do |buffer|
175
- @frame_encoder.encode(buffer, request, id)
176
- end
183
+ write_request(id, promise)
177
184
  else
178
185
  @lock.lock
179
186
  begin
@@ -182,11 +189,6 @@ module Cassandra
182
189
  @lock.unlock
183
190
  end
184
191
  end
185
- if timeout
186
- @scheduler.schedule_timer(timeout).on_value do
187
- promise.time_out!
188
- end
189
- end
190
192
  promise.future
191
193
  end
192
194
 
@@ -234,38 +236,39 @@ module Cassandra
234
236
  ensure
235
237
  @lock.unlock
236
238
  end
237
- if response.is_a?(Protocol::SetKeyspaceResultResponse)
238
- @keyspace = response.keyspace
239
- end
240
- if response.is_a?(Protocol::SchemaChangeResultResponse) && response.change == 'DROPPED' && response.keyspace == @keyspace && response.target == Protocol::Constants::SCHEMA_CHANGE_TARGET_KEYSPACE
239
+ @keyspace = response.keyspace if response.is_a?(Protocol::SetKeyspaceResultResponse)
240
+ if response.is_a?(Protocol::SchemaChangeResultResponse) &&
241
+ response.change == 'DROPPED' &&
242
+ response.keyspace == @keyspace &&
243
+ response.target == Protocol::Constants::SCHEMA_CHANGE_TARGET_KEYSPACE
241
244
  @keyspace = nil
242
245
  end
243
246
  flush_request_queue
244
- unless promise.timed_out?
245
- promise.fulfill(response)
246
- end
247
+ promise.fulfill(response) unless promise.timed_out?
247
248
  end
248
249
 
249
250
  private
250
251
 
251
252
  # @private
252
253
  class RequestPromise < Ione::Promise
253
- attr_reader :request
254
+ extend AttrBoolean
254
255
 
255
- def initialize(request)
256
+ attr_reader :request, :timeout
257
+ attr_boolean :timed_out
258
+
259
+ def initialize(request, timeout)
256
260
  @request = request
261
+ @timeout = timeout
257
262
  @timed_out = false
258
263
  super()
259
264
  end
260
265
 
261
- def timed_out?
262
- @timed_out
263
- end
264
-
265
266
  def time_out!
266
267
  unless future.completed?
267
268
  @timed_out = true
269
+ # rubocop:disable Style/SignalException
268
270
  fail(Errors::TimeoutError.new('Timed out'))
271
+ # rubocop:enable Style/SignalException
269
272
  end
270
273
  end
271
274
  end
@@ -285,28 +288,32 @@ module Cassandra
285
288
  ensure
286
289
  @lock.unlock
287
290
  end
288
- while true
291
+ loop do
289
292
  id = nil
290
293
  promise = nil
291
294
  @lock.lock
292
295
  begin
293
296
  if @request_queue_out.any? && (id = next_stream_id)
294
297
  promise = @request_queue_out.shift
295
- if promise.timed_out?
296
- next
297
- else
298
- @promises[id] = promise
299
- end
298
+ next if promise.timed_out?
299
+ @promises[id] = promise
300
300
  end
301
301
  ensure
302
302
  @lock.unlock
303
303
  end
304
- if id
305
- @connection.write do |buffer|
306
- @frame_encoder.encode(buffer, promise.request, id)
307
- end
308
- else
309
- break
304
+
305
+ break unless id
306
+ write_request(id, promise)
307
+ end
308
+ end
309
+
310
+ def write_request(id, request_promise)
311
+ @connection.write do |buffer|
312
+ @frame_encoder.encode(buffer, request_promise.request, id)
313
+ end
314
+ if request_promise.timeout
315
+ @scheduler.schedule_timer(request_promise.timeout).on_value do
316
+ request_promise.time_out!
310
317
  end
311
318
  end
312
319
  end
@@ -382,11 +389,7 @@ module Cassandra
382
389
  end
383
390
 
384
391
  def next_stream_id
385
- if (stream_id = @streams.shift)
386
- stream_id
387
- else
388
- nil
389
- end
392
+ @streams.shift
390
393
  end
391
394
 
392
395
  HEARTBEAT = OptionsRequest.new