cql-rb 1.2.2 → 2.0.0.pre0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +4 -0
  3. data/README.md +139 -17
  4. data/lib/cql/client.rb +237 -8
  5. data/lib/cql/client/asynchronous_client.rb +138 -54
  6. data/lib/cql/client/asynchronous_prepared_statement.rb +41 -6
  7. data/lib/cql/client/authenticators.rb +46 -0
  8. data/lib/cql/client/batch.rb +115 -0
  9. data/lib/cql/client/connector.rb +255 -0
  10. data/lib/cql/client/execute_options_decoder.rb +25 -9
  11. data/lib/cql/client/keyspace_changer.rb +5 -5
  12. data/lib/cql/client/peer_discovery.rb +33 -0
  13. data/lib/cql/client/query_result.rb +124 -1
  14. data/lib/cql/client/request_runner.rb +4 -2
  15. data/lib/cql/client/synchronous_client.rb +14 -2
  16. data/lib/cql/client/synchronous_prepared_statement.rb +19 -1
  17. data/lib/cql/future.rb +97 -50
  18. data/lib/cql/io/connection.rb +0 -1
  19. data/lib/cql/io/io_reactor.rb +1 -1
  20. data/lib/cql/protocol.rb +8 -1
  21. data/lib/cql/protocol/cql_protocol_handler.rb +2 -2
  22. data/lib/cql/protocol/decoding.rb +10 -15
  23. data/lib/cql/protocol/frame_decoder.rb +2 -1
  24. data/lib/cql/protocol/frame_encoder.rb +5 -4
  25. data/lib/cql/protocol/requests/auth_response_request.rb +31 -0
  26. data/lib/cql/protocol/requests/batch_request.rb +59 -0
  27. data/lib/cql/protocol/requests/credentials_request.rb +1 -1
  28. data/lib/cql/protocol/requests/execute_request.rb +45 -17
  29. data/lib/cql/protocol/requests/options_request.rb +1 -1
  30. data/lib/cql/protocol/requests/prepare_request.rb +1 -1
  31. data/lib/cql/protocol/requests/query_request.rb +97 -5
  32. data/lib/cql/protocol/requests/register_request.rb +1 -1
  33. data/lib/cql/protocol/requests/startup_request.rb +4 -4
  34. data/lib/cql/protocol/response.rb +2 -2
  35. data/lib/cql/protocol/responses/auth_challenge_response.rb +25 -0
  36. data/lib/cql/protocol/responses/auth_success_response.rb +25 -0
  37. data/lib/cql/protocol/responses/authenticate_response.rb +1 -1
  38. data/lib/cql/protocol/responses/detailed_error_response.rb +1 -1
  39. data/lib/cql/protocol/responses/error_response.rb +3 -2
  40. data/lib/cql/protocol/responses/event_response.rb +3 -2
  41. data/lib/cql/protocol/responses/prepared_result_response.rb +10 -6
  42. data/lib/cql/protocol/responses/raw_rows_result_response.rb +27 -0
  43. data/lib/cql/protocol/responses/ready_response.rb +1 -1
  44. data/lib/cql/protocol/responses/result_response.rb +2 -2
  45. data/lib/cql/protocol/responses/rows_result_response.rb +43 -23
  46. data/lib/cql/protocol/responses/schema_change_event_response.rb +1 -1
  47. data/lib/cql/protocol/responses/schema_change_result_response.rb +1 -1
  48. data/lib/cql/protocol/responses/set_keyspace_result_response.rb +1 -1
  49. data/lib/cql/protocol/responses/status_change_event_response.rb +1 -1
  50. data/lib/cql/protocol/responses/supported_response.rb +1 -1
  51. data/lib/cql/protocol/responses/void_result_response.rb +1 -1
  52. data/lib/cql/protocol/type_converter.rb +2 -2
  53. data/lib/cql/uuid.rb +2 -2
  54. data/lib/cql/version.rb +1 -1
  55. data/spec/cql/client/asynchronous_client_spec.rb +493 -50
  56. data/spec/cql/client/asynchronous_prepared_statement_spec.rb +193 -11
  57. data/spec/cql/client/authenticators_spec.rb +56 -0
  58. data/spec/cql/client/batch_spec.rb +277 -0
  59. data/spec/cql/client/connector_spec.rb +606 -0
  60. data/spec/cql/client/execute_options_decoder_spec.rb +95 -0
  61. data/spec/cql/client/keyspace_changer_spec.rb +8 -8
  62. data/spec/cql/client/peer_discovery_spec.rb +92 -0
  63. data/spec/cql/client/query_result_spec.rb +352 -0
  64. data/spec/cql/client/request_runner_spec.rb +31 -5
  65. data/spec/cql/client/synchronous_client_spec.rb +44 -1
  66. data/spec/cql/client/synchronous_prepared_statement_spec.rb +63 -1
  67. data/spec/cql/future_spec.rb +50 -2
  68. data/spec/cql/protocol/cql_protocol_handler_spec.rb +16 -5
  69. data/spec/cql/protocol/decoding_spec.rb +16 -6
  70. data/spec/cql/protocol/encoding_spec.rb +3 -1
  71. data/spec/cql/protocol/frame_encoder_spec.rb +99 -50
  72. data/spec/cql/protocol/requests/auth_response_request_spec.rb +62 -0
  73. data/spec/cql/protocol/requests/batch_request_spec.rb +155 -0
  74. data/spec/cql/protocol/requests/credentials_request_spec.rb +1 -1
  75. data/spec/cql/protocol/requests/execute_request_spec.rb +184 -71
  76. data/spec/cql/protocol/requests/options_request_spec.rb +1 -1
  77. data/spec/cql/protocol/requests/prepare_request_spec.rb +1 -1
  78. data/spec/cql/protocol/requests/query_request_spec.rb +255 -32
  79. data/spec/cql/protocol/requests/register_request_spec.rb +1 -1
  80. data/spec/cql/protocol/requests/startup_request_spec.rb +12 -6
  81. data/spec/cql/protocol/responses/auth_challenge_response_spec.rb +31 -0
  82. data/spec/cql/protocol/responses/auth_success_response_spec.rb +31 -0
  83. data/spec/cql/protocol/responses/authenticate_response_spec.rb +2 -1
  84. data/spec/cql/protocol/responses/detailed_error_response_spec.rb +14 -7
  85. data/spec/cql/protocol/responses/error_response_spec.rb +4 -2
  86. data/spec/cql/protocol/responses/event_response_spec.rb +7 -4
  87. data/spec/cql/protocol/responses/prepared_result_response_spec.rb +89 -34
  88. data/spec/cql/protocol/responses/raw_rows_result_response_spec.rb +66 -0
  89. data/spec/cql/protocol/responses/ready_response_spec.rb +1 -1
  90. data/spec/cql/protocol/responses/result_response_spec.rb +19 -7
  91. data/spec/cql/protocol/responses/rows_result_response_spec.rb +56 -11
  92. data/spec/cql/protocol/responses/schema_change_event_response_spec.rb +2 -1
  93. data/spec/cql/protocol/responses/schema_change_result_response_spec.rb +2 -1
  94. data/spec/cql/protocol/responses/set_keyspace_result_response_spec.rb +1 -1
  95. data/spec/cql/protocol/responses/status_change_event_response_spec.rb +2 -1
  96. data/spec/cql/protocol/responses/supported_response_spec.rb +2 -1
  97. data/spec/cql/protocol/responses/topology_change_event_response_spec.rb +2 -1
  98. data/spec/cql/protocol/responses/void_result_response_spec.rb +1 -1
  99. data/spec/cql/protocol/type_converter_spec.rb +21 -4
  100. data/spec/cql/uuid_spec.rb +10 -3
  101. data/spec/integration/client_spec.rb +251 -28
  102. data/spec/integration/protocol_spec.rb +213 -62
  103. data/spec/integration/regression_spec.rb +4 -1
  104. data/spec/integration/uuid_spec.rb +4 -1
  105. data/spec/support/fake_io_reactor.rb +5 -5
  106. metadata +36 -7
  107. data/lib/cql/client/connection_helper.rb +0 -181
  108. data/spec/cql/client/connection_helper_spec.rb +0 -429
@@ -4,11 +4,13 @@ module Cql
4
4
  module Client
5
5
  # @private
6
6
  class RequestRunner
7
- def execute(connection, request, timeout=nil)
7
+ def execute(connection, request, timeout=nil, raw_metadata=nil)
8
8
  connection.send_request(request, timeout).map do |response|
9
9
  case response
10
+ when Protocol::RawRowsResultResponse
11
+ LazyQueryResult.new(raw_metadata, response, response.trace_id, response.paging_state)
10
12
  when Protocol::RowsResultResponse
11
- QueryResult.new(response.metadata, response.rows, response.trace_id)
13
+ QueryResult.new(response.metadata, response.rows, response.trace_id, response.paging_state)
12
14
  when Protocol::VoidResultResponse
13
15
  response.trace_id ? VoidResult.new(response.trace_id) : VoidResult::INSTANCE
14
16
  when Protocol::ErrorResponse
@@ -50,8 +50,12 @@ module Cql
50
50
  synchronous_backtrace { @async_client.use(keyspace).value }
51
51
  end
52
52
 
53
- def execute(cql, consistency=nil)
54
- synchronous_backtrace { @async_client.execute(cql, consistency).value }
53
+ def execute(cql, *args)
54
+ synchronous_backtrace do
55
+ result = @async_client.execute(cql, *args).value
56
+ result = SynchronousPagedQueryResult.new(result) if result.is_a?(PagedQueryResult)
57
+ result
58
+ end
55
59
  end
56
60
 
57
61
  def prepare(cql)
@@ -59,6 +63,14 @@ module Cql
59
63
  SynchronousPreparedStatement.new(async_statement)
60
64
  end
61
65
 
66
+ def batch(type=:logged, options={}, &block)
67
+ if block_given?
68
+ synchronous_backtrace { @async_client.batch(type, options, &block).value }
69
+ else
70
+ SynchronousBatch.new(@async_client.batch(type, options))
71
+ end
72
+ end
73
+
62
74
  def async
63
75
  @async_client
64
76
  end
@@ -9,10 +9,23 @@ module Cql
9
9
  def initialize(async_statement)
10
10
  @async_statement = async_statement
11
11
  @metadata = async_statement.metadata
12
+ @result_metadata = async_statement.result_metadata
12
13
  end
13
14
 
14
15
  def execute(*args)
15
- synchronous_backtrace { @async_statement.execute(*args).value }
16
+ synchronous_backtrace do
17
+ result = @async_statement.execute(*args).value
18
+ result = SynchronousPagedQueryResult.new(result) if result.is_a?(PagedQueryResult)
19
+ result
20
+ end
21
+ end
22
+
23
+ def batch(type=:logged, options=nil, &block)
24
+ if block_given?
25
+ synchronous_backtrace { @async_statement.batch(type, options, &block).value }
26
+ else
27
+ SynchronousPreparedStatementBatch.new(@async_statement.batch(type, options))
28
+ end
16
29
  end
17
30
 
18
31
  def pipeline
@@ -24,6 +37,11 @@ module Cql
24
37
  def async
25
38
  @async_statement
26
39
  end
40
+
41
+ # @private
42
+ def add_to_batch(batch, connection, bound_arguments)
43
+ @async_statement.add_to_batch(batch, connection, bound_arguments)
44
+ end
27
45
  end
28
46
 
29
47
  # @private
@@ -88,11 +88,8 @@ module Cql
88
88
  # @return [Cql::Future<Array>] an array of the values of the constituent
89
89
  # futures
90
90
  def all(*futures)
91
- if futures.any?
92
- CombinedFuture.new(futures)
93
- else
94
- resolved([])
95
- end
91
+ return resolved([]) if futures.empty?
92
+ CombinedFuture.new(futures)
96
93
  end
97
94
 
98
95
  # Returns a future which will be resolved with the value of the first
@@ -102,11 +99,8 @@ module Cql
102
99
  # @param [Array<Cql::Future>] futures the futures to monitor
103
100
  # @return [Cql::Future] a future which represents the first completing future
104
101
  def first(*futures)
105
- if futures.any?
106
- FirstFuture.new(futures)
107
- else
108
- resolved
109
- end
102
+ return resolved if futures.empty?
103
+ FirstFuture.new(futures)
110
104
  end
111
105
 
112
106
  # Creates a new pre-resolved future.
@@ -133,16 +127,15 @@ module Cql
133
127
  # @example
134
128
  # future2 = future1.map { |value| value * 2 }
135
129
  #
130
+ # @param [Object] value the value of this future (when no block is given)
136
131
  # @yieldparam [Object] value the value of this future
137
132
  # @yieldreturn [Object] the transformed value
138
133
  # @return [Cql::Future] a new future representing the transformed value
139
- def map(&block)
140
- p = Promise.new
141
- on_failure { |e| p.fail(e) }
142
- on_value do |v|
143
- p.try(v, &block)
134
+ def map(value=nil, &block)
135
+ CompletableFuture.new.tap do |f|
136
+ on_failure { |e| f.fail(e) }
137
+ on_value { |v| run(f, value, block, v) }
144
138
  end
145
- p.future
146
139
  end
147
140
 
148
141
  # Returns a new future representing a transformation of this future's value,
@@ -157,17 +150,10 @@ module Cql
157
150
  # @yieldreturn [Cql::Future] a future representing the transformed value
158
151
  # @return [Cql::Future] a new future representing the transformed value
159
152
  def flat_map(&block)
160
- p = Promise.new
161
- on_failure { |e| p.fail(e) }
162
- on_value do |v|
163
- begin
164
- f = block.call(v)
165
- p.observe(f)
166
- rescue => e
167
- p.fail(e)
168
- end
153
+ CompletableFuture.new.tap do |f|
154
+ on_failure { |e| f.fail(e) }
155
+ on_value { |v| chain(f, block, v) }
169
156
  end
170
- p.future
171
157
  end
172
158
 
173
159
  # Returns a new future which represents either the value of the original
@@ -185,18 +171,15 @@ module Cql
185
171
  # future1.fail(error)
186
172
  # future2.value # => 'foo'
187
173
  #
174
+ # @param [Object] value the value when no block is given
188
175
  # @yieldparam [Object] error the error from the original future
189
176
  # @yieldreturn [Object] the value of the new future
190
177
  # @return [Cql::Future] a new future representing a value recovered from the error
191
- def recover(&block)
192
- p = Promise.new
193
- on_failure do |e|
194
- p.try(e, &block)
195
- end
196
- on_value do |v|
197
- p.fulfill(v)
178
+ def recover(value=nil, &block)
179
+ CompletableFuture.new.tap do |f|
180
+ on_failure { |e| run(f, value, block, e) }
181
+ on_value { |v| f.resolve(v) }
198
182
  end
199
- p.future
200
183
  end
201
184
 
202
185
  # Returns a new future which represents either the value of the original
@@ -222,19 +205,27 @@ module Cql
222
205
  # @return [Cql::Future] a new future representing a value recovered from the
223
206
  # error
224
207
  def fallback(&block)
225
- p = Promise.new
226
- on_failure do |e|
227
- begin
228
- f = block.call(e)
229
- p.observe(f)
230
- rescue => e
231
- p.fail(e)
232
- end
233
- end
234
- on_value do |v|
235
- p.fulfill(v)
208
+ CompletableFuture.new.tap do |f|
209
+ on_failure { |e| chain(f, block, e) }
210
+ on_value { |v| f.resolve(v) }
236
211
  end
237
- p.future
212
+ end
213
+
214
+ private
215
+
216
+ def run(f, value, producer, arg)
217
+ value = producer ? producer.call(arg) : value
218
+ f.resolve(value)
219
+ rescue => e
220
+ f.fail(e)
221
+ end
222
+
223
+ def chain(f, constructor, arg)
224
+ ff = constructor.call(arg)
225
+ ff.on_failure { |e| f.fail(e) }
226
+ ff.on_value { |v| f.resolve(v) }
227
+ rescue => e
228
+ f.fail(e)
238
229
  end
239
230
  end
240
231
 
@@ -451,18 +442,74 @@ module Cql
451
442
  # @private
452
443
  class ResolvedFuture < Future
453
444
  def initialize(value=nil)
454
- super()
455
- @value = value
456
445
  @resolved = true
446
+ @failed = false
447
+ @value = value
448
+ @error = nil
449
+ end
450
+
451
+ def value
452
+ @value
453
+ end
454
+
455
+ def completed?
456
+ true
457
+ end
458
+
459
+ def resolved?
460
+ true
461
+ end
462
+
463
+ def failed?
464
+ false
465
+ end
466
+
467
+ def on_complete(&listener)
468
+ listener.call(self) rescue nil
469
+ end
470
+
471
+ def on_value(&listener)
472
+ listener.call(value) rescue nil
473
+ end
474
+
475
+ def on_failure
457
476
  end
458
477
  end
459
478
 
460
479
  # @private
461
480
  class FailedFuture < Future
462
481
  def initialize(error)
463
- super()
464
- @error = error
482
+ @resolved = false
465
483
  @failed = true
484
+ @value = nil
485
+ @error = error
486
+ end
487
+
488
+ def value
489
+ raise @error
490
+ end
491
+
492
+ def completed?
493
+ true
494
+ end
495
+
496
+ def resolved?
497
+ false
498
+ end
499
+
500
+ def failed?
501
+ true
502
+ end
503
+
504
+ def on_complete(&listener)
505
+ listener.call(self) rescue nil
506
+ end
507
+
508
+ def on_value
509
+ end
510
+
511
+ def on_failure(&listener)
512
+ listener.call(@error) rescue nil
466
513
  end
467
514
  end
468
515
  end
@@ -167,7 +167,6 @@ module Cql
167
167
  def flush
168
168
  if writable?
169
169
  @lock.synchronize do
170
- s = @write_buffer.cheap_peek.dup
171
170
  bytes_written = @io.write_nonblock(@write_buffer.cheap_peek)
172
171
  @write_buffer.discard(bytes_written)
173
172
  end
@@ -192,7 +192,7 @@ module Cql
192
192
  protocol_handler = @protocol_handler_factory.call(connection, self)
193
193
  @io_loop.add_socket(connection)
194
194
  @unblocker.unblock!
195
- f.map { protocol_handler }
195
+ f.map(protocol_handler)
196
196
  end
197
197
 
198
198
  # Returns a future that completes after the specified number of seconds.
@@ -14,9 +14,11 @@ module Cql
14
14
  UnsupportedResultKindError = Class.new(ProtocolError)
15
15
  UnsupportedColumnTypeError = Class.new(ProtocolError)
16
16
  UnsupportedEventTypeError = Class.new(ProtocolError)
17
+ UnsupportedFeatureError = Class.new(ProtocolError)
17
18
  UnexpectedCompressionError = Class.new(ProtocolError)
19
+ UnmaterializedRowsError = Class.new(ProtocolError)
18
20
 
19
- CONSISTENCIES = [:any, :one, :two, :three, :quorum, :all, :local_quorum, :each_quorum, nil, nil, nil, nil, nil, nil, nil, nil, :local_one].freeze
21
+ CONSISTENCIES = [:any, :one, :two, :three, :quorum, :all, :local_quorum, :each_quorum, :serial, :local_serial, :local_one].freeze
20
22
 
21
23
  module Formats
22
24
  CHAR_FORMAT = 'c'.freeze
@@ -43,6 +45,8 @@ require 'cql/protocol/encoding'
43
45
  require 'cql/protocol/decoding'
44
46
  require 'cql/protocol/type_converter'
45
47
  require 'cql/protocol/response'
48
+ require 'cql/protocol/responses/auth_challenge_response'
49
+ require 'cql/protocol/responses/auth_success_response'
46
50
  require 'cql/protocol/responses/error_response'
47
51
  require 'cql/protocol/responses/detailed_error_response'
48
52
  require 'cql/protocol/responses/ready_response'
@@ -51,6 +55,7 @@ require 'cql/protocol/responses/supported_response'
51
55
  require 'cql/protocol/responses/result_response'
52
56
  require 'cql/protocol/responses/void_result_response'
53
57
  require 'cql/protocol/responses/rows_result_response'
58
+ require 'cql/protocol/responses/raw_rows_result_response'
54
59
  require 'cql/protocol/responses/set_keyspace_result_response'
55
60
  require 'cql/protocol/responses/prepared_result_response'
56
61
  require 'cql/protocol/responses/schema_change_result_response'
@@ -59,6 +64,8 @@ require 'cql/protocol/responses/schema_change_event_response'
59
64
  require 'cql/protocol/responses/status_change_event_response'
60
65
  require 'cql/protocol/responses/topology_change_event_response'
61
66
  require 'cql/protocol/request'
67
+ require 'cql/protocol/requests/auth_response_request'
68
+ require 'cql/protocol/requests/batch_request'
62
69
  require 'cql/protocol/requests/startup_request'
63
70
  require 'cql/protocol/requests/credentials_request'
64
71
  require 'cql/protocol/requests/options_request'
@@ -19,7 +19,7 @@ module Cql
19
19
  # @return [String] the current keyspace for the underlying connection
20
20
  attr_reader :keyspace
21
21
 
22
- def initialize(connection, scheduler, compressor=nil)
22
+ def initialize(connection, scheduler, protocol_version, compressor=nil)
23
23
  @connection = connection
24
24
  @scheduler = scheduler
25
25
  @compressor = compressor
@@ -27,7 +27,7 @@ module Cql
27
27
  @connection.on_closed(&method(:socket_closed))
28
28
  @promises = Array.new(128) { nil }
29
29
  @read_buffer = ByteBuffer.new
30
- @frame_encoder = FrameEncoder.new(@compressor)
30
+ @frame_encoder = FrameEncoder.new(protocol_version, @compressor)
31
31
  @frame_decoder = FrameDecoder.new(@compressor)
32
32
  @current_frame = FrameDecoder::NULL_FRAME
33
33
  @request_queue_in = []
@@ -46,19 +46,16 @@ module Cql
46
46
  fraction_string << number_string[number_string.length - size, number_string.length]
47
47
  end
48
48
  BigDecimal.new(fraction_string)
49
- rescue RangeError => e
49
+ rescue DecodingError => e
50
50
  raise DecodingError, e.message, e.backtrace
51
51
  end
52
52
 
53
53
  def read_long!(buffer)
54
- hi, lo = buffer.read(8).unpack(Formats::TWO_INTS_FORMAT)
55
- if (hi > 0x7fffffff)
56
- hi ^= 0xffffffff
57
- lo ^= 0xffffffff
58
- 0 - (hi << 32) - lo - 1
59
- else
60
- (hi << 32) + lo
61
- end
54
+ top, bottom = buffer.read(8).unpack(Formats::TWO_INTS_FORMAT)
55
+ return (top << 32) | bottom if top <= 0x7fffffff
56
+ top ^= 0xffffffff
57
+ bottom ^= 0xffffffff
58
+ -((top << 32) | bottom) - 1
62
59
  rescue RangeError => e
63
60
  raise DecodingError, e.message, e.backtrace
64
61
  end
@@ -76,11 +73,9 @@ module Cql
76
73
  end
77
74
 
78
75
  def read_int!(buffer)
79
- val = buffer.read_int
80
- if (val > 0x7fffffff)
81
- val = 0 - ((val - 1) ^ 0xffffffff)
82
- end
83
- val
76
+ n = buffer.read_int
77
+ return n if n <= 0x7fffffff
78
+ n - 0xffffffff - 1
84
79
  rescue RangeError => e
85
80
  raise DecodingError, "Not enough bytes available to decode an int: #{e.message}", e.backtrace
86
81
  end
@@ -111,7 +106,7 @@ module Cql
111
106
 
112
107
  def read_uuid!(buffer, impl=Uuid)
113
108
  impl.new(read_varint!(buffer, 16, false))
114
- rescue RangeError => e
109
+ rescue DecodingError => e
115
110
  raise DecodingError, "Not enough bytes available to decode a UUID: #{e.message}", e.backtrace
116
111
  end
117
112
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  module Cql
4
4
  module Protocol
5
+ # @private
5
6
  class FrameDecoder
6
7
  def initialize(compressor=nil)
7
8
  @compressor = compressor
@@ -44,7 +45,7 @@ module Cql
44
45
  end
45
46
  extra_length = buffer.length - size
46
47
  trace_id = tracing == 2 ? Decoding.read_uuid!(buffer) : nil
47
- response = Response.decode!(opcode, buffer, trace_id)
48
+ response = Response.decode!(opcode, protocol_version, buffer, size, trace_id)
48
49
  if buffer.length > extra_length
49
50
  buffer.discard(buffer.length - extra_length)
50
51
  end
@@ -2,22 +2,23 @@
2
2
 
3
3
  module Cql
4
4
  module Protocol
5
+ # @private
5
6
  class FrameEncoder
6
- def initialize(compressor=nil)
7
+ def initialize(protocol_version=1, compressor=nil)
8
+ @protocol_version = protocol_version
7
9
  @compressor = compressor
8
10
  end
9
11
 
10
12
  def encode_frame(request, stream_id=0, buffer=nil)
11
13
  raise InvalidStreamIdError, 'The stream ID must be between 0 and 127' unless 0 <= stream_id && stream_id < 128
12
14
  buffer ||= ByteBuffer.new
13
- offset = buffer.bytesize
14
15
  flags = request.trace? ? 2 : 0
15
- body = request.write(ByteBuffer.new)
16
+ body = request.write(@protocol_version, ByteBuffer.new)
16
17
  if @compressor && request.compressable? && @compressor.compress?(body)
17
18
  flags |= 1
18
19
  body = @compressor.compress(body)
19
20
  end
20
- header = [1, flags, stream_id, request.opcode, body.bytesize]
21
+ header = [@protocol_version, flags, stream_id, request.opcode, body.bytesize]
21
22
  buffer << header.pack(Formats::HEADER_FORMAT)
22
23
  buffer << body
23
24
  buffer