cql-rb 1.0.0.pre8 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,7 +1,5 @@
1
1
  # Ruby CQL3 driver
2
2
 
3
- _There has not yet been a stable release of this project._
4
-
5
3
  [![Build Status](https://travis-ci.org/iconara/cql-rb.png?branch=master)](https://travis-ci.org/iconara/cql-rb)
6
4
 
7
5
  # Requirements
@@ -10,11 +8,11 @@ Cassandra 1.2 with the native transport protocol turned on and a modern Ruby. Te
10
8
 
11
9
  # Installation
12
10
 
13
- gem install --prerelease cql-rb
11
+ gem install cql-rb
14
12
 
15
13
  ## Configure Cassandra
16
14
 
17
- The native transport protocol (sometimes called binary protocol, or CQL protocol) is not on by default in Cassandra 1.2, to enable it edit the `cassandra.yaml` file on all nodes in your cluster and set `start_native_transport` to `true`. You need to restart the nodes for this to have effect.
15
+ If you're running Cassandra 1.2.5 the native transport protocol is enabled by default, if you're running an earlier version (but later than 1.2) you must enable it by editing `cassandra.yaml` and setting `start_native_transport` to `true`.
18
16
 
19
17
  # Quick start
20
18
 
@@ -25,12 +23,14 @@ client = Cql::Client.connect(host: 'cassandra.example.com')
25
23
  client.use('system')
26
24
  rows = client.execute('SELECT keyspace_name, columnfamily_name FROM schema_columnfamilies')
27
25
  rows.each do |row|
28
- puts "The keyspace #{row['keyspace_name']} has a table called #{row['columnfamily_name']}""
26
+ puts "The keyspace #{row['keyspace_name']} has a table called #{row['columnfamily_name']}"
29
27
  end
30
28
  ```
31
29
 
32
30
  when you're done you can call `#close` to disconnect from Cassandra. You can connect to multiple Cassandra nodes by passing multiple comma separated host names to the `:host` option.
33
31
 
32
+ # Usage
33
+
34
34
  ## Changing keyspaces
35
35
 
36
36
  ```ruby
@@ -117,7 +117,7 @@ At this time prepared statements are local to a single connection. Even if you c
117
117
 
118
118
  # Consistency levels
119
119
 
120
- The `#execute` method supports setting the desired consistency level for the statement:
120
+ The `#execute` (of `Client` and `PreparedStatement`) method supports setting the desired consistency level for the statement:
121
121
 
122
122
  ```ruby
123
123
  client.execute('SELECT * FROM peers', :local_quorum)
@@ -144,14 +144,73 @@ This is just a driver for the Cassandra native CQL protocol, it doesn't really k
144
144
 
145
145
  Read more about CQL3 in the [CQL3 syntax documentation](https://github.com/apache/cassandra/blob/cassandra-1.2/doc/cql3/CQL.textile) and the [Cassandra query documentation](http://www.datastax.com/docs/1.2/cql_cli/querying_cql).
146
146
 
147
+ # Troubleshooting
148
+
149
+ ## I get "Deadlock detected" errors
150
+
151
+ This means that the driver's IO reactor has crashed hard. Most of the time it means that you're using a framework, server or runtime that forks and you call `Client.connect` in the parent process. Check the documentation and see if there's any way you can register to run some piece of code in the child process just after a fork.
152
+
153
+ This is how you do it in Resque:
154
+
155
+ ```ruby
156
+ Resque.after_fork = proc do
157
+ # ...
158
+ end
159
+ ```
160
+
161
+ and this is how you do it in Passenger:
162
+
163
+ ```ruby
164
+ PhusionPassenger.on_event(:starting_worker_process) do |forked|
165
+ if forked
166
+ # ...
167
+ end
168
+ end
169
+ ```
170
+
171
+ in Unicorn you do it in the config file:
172
+
173
+ ```ruby
174
+ after_fork do |server, worker|
175
+ # ...
176
+ end
177
+ ```
178
+
179
+ If your process does not fork and you still encounter deadlock errors, it might also be a bug. All IO is done is a dedicated thread, and if something happens that makes that thread shut down, Ruby will detect that the locks that the client code is waiting on can't be unlocked.
180
+
181
+ ## I'm not getting all elements back from my list/set/map
182
+
183
+ There's a known issue with collections that get too big. The protocol uses a short for the size of collections, but there is no way for Cassandra to stop you from creating a collection bigger than 65536 elements, so when you do the size field overflows with strange results. The data is there, you just can't get it back.
184
+
185
+ ## The error backtraces are weird
186
+
187
+ Yeah, sorry. All IO is asynchronous, and when an error is returned from Cassandra the call stack from when the request was issued is gone. `QueryError` has a `#cql` field that contains the CQL for the request that failed, hopefully that gives you enough information to understand where the error originated.
188
+
189
+ ## Authentication doesn't work
190
+
191
+ Please open an issue. It should be working, but it's hard to write tests for, so there may be edge cases that aren't covered.
192
+
193
+ ## I'm connecting to port 9160 and it doesn't work
194
+
195
+ Port 9160 is the old Thrift interface, the binary protocol runs on 9042. This is also the default port for cql-rb, so unless you've changed the port in `cassandra.yaml`, don't override the port.
196
+
197
+ ## One of my Cassandra nodes crashed, and my application crashed, isn't Cassandra supposed to be fault tolerant?
198
+
199
+ Yes it is, and your data is probably safe. cql-rb is just not completely there yet. Ideally it should handle connectivity issues and just talk to the nodes it can talk to and reconnect when things get back to normal. It's on the roadmap.
200
+
201
+ ## Something else is not working
202
+
203
+ Open an issue and I'll do my best to help you. Please include the gem version, Casandra version and Ruby version, and explain as much about what you're doing as you can, preferably the smallest piece of code that reliably triggers the problem.
204
+
147
205
  # Known bugs & limitations
148
206
 
149
- * There are still edge cases around connection errors, and there is no automatic reconnection.
150
- * JRuby 1.6.8 is not supported, although it should be. The only known issue is that connection failures aren't handled gracefully.
151
207
  * No automatic peer discovery.
208
+ * No automatic reconnection on connection failures.
209
+ * JRuby 1.6.8 and earlier is not supported, although it probably works fine. The only known issue is that connection failures aren't handled gracefully.
152
210
  * Compression is not supported.
153
211
  * Large results are buffered in memory until the whole response has been loaded, the protocol makes it possible to start to deliver rows to the client code as soon as the metadata is loaded, but this is not supported yet.
154
212
  * There is no cluster introspection utilities (like the `DESCRIBE` commands in `cqlsh`).
213
+ * No support for request tracing.
155
214
 
156
215
  ## Copyright
157
216
 
@@ -92,7 +92,7 @@ module Cql
92
92
 
93
93
  def perform_request(request, future)
94
94
  stream_id = next_stream_id
95
- @write_buffer << request.encode_frame(stream_id)
95
+ request.encode_frame(stream_id, @write_buffer)
96
96
  @response_tasks[stream_id] = future
97
97
  rescue => e
98
98
  case e
@@ -13,9 +13,10 @@ module Cql
13
13
 
14
14
  def encode_frame(stream_id=0, buffer=ByteBuffer.new)
15
15
  raise InvalidStreamIdError, 'The stream ID must be between 0 and 127' unless 0 <= stream_id && stream_id < 128
16
+ offset = buffer.bytesize
16
17
  buffer << [1, 0, stream_id, opcode, 0].pack(Formats::HEADER_FORMAT)
17
18
  write(buffer)
18
- buffer.update(4, [(buffer.bytesize - 8)].pack(Formats::INT_FORMAT))
19
+ buffer.update(offset + 4, [(buffer.bytesize - offset - 8)].pack(Formats::INT_FORMAT))
19
20
  buffer
20
21
  end
21
22
  end
data/lib/cql/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module Cql
4
- VERSION = '1.0.0.pre8'.freeze
4
+ VERSION = '1.0.0'.freeze
5
5
  end
@@ -8,8 +8,20 @@ module Cql
8
8
  describe Request do
9
9
  describe '#encode_frame' do
10
10
  it 'returns a rendered request frame for the specified channel' do
11
- frame = PrepareRequest.new('SELECT * FROM things').encode_frame(3)
12
- frame.to_s.should == "\x01\x00\x03\x09\x00\x00\x00\x18\x00\x00\x00\x14SELECT * FROM things"
11
+ encoded_frame = PrepareRequest.new('SELECT * FROM things').encode_frame(3)
12
+ encoded_frame.to_s.should == "\x01\x00\x03\x09\x00\x00\x00\x18\x00\x00\x00\x14SELECT * FROM things"
13
+ end
14
+
15
+ it 'appends a rendered request frame to the specified buffer' do
16
+ buffer = ByteBuffer.new('hello')
17
+ encoded_frame = PrepareRequest.new('SELECT * FROM things').encode_frame(3, buffer)
18
+ buffer.to_s.should == "hello\x01\x00\x03\x09\x00\x00\x00\x18\x00\x00\x00\x14SELECT * FROM things"
19
+ end
20
+
21
+ it 'returns the specified buffer' do
22
+ buffer = ByteBuffer.new('hello')
23
+ encoded_frame = PrepareRequest.new('SELECT * FROM things').encode_frame(3, buffer)
24
+ encoded_frame.should equal(buffer)
13
25
  end
14
26
  end
15
27
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cql-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.pre8
5
- prerelease: 6
4
+ version: 1.0.0
5
+ prerelease:
6
6
  platform: ruby
7
7
  authors:
8
8
  - Theo Hultberg
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-06-07 00:00:00.000000000 Z
12
+ date: 2013-06-13 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: A pure Ruby CQL3 driver for Cassandra
15
15
  email:
@@ -108,9 +108,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
108
108
  required_rubygems_version: !ruby/object:Gem::Requirement
109
109
  none: false
110
110
  requirements:
111
- - - ! '>'
111
+ - - ! '>='
112
112
  - !ruby/object:Gem::Version
113
- version: 1.3.1
113
+ version: '0'
114
+ segments:
115
+ - 0
116
+ hash: -3274197899140325066
114
117
  requirements: []
115
118
  rubyforge_project:
116
119
  rubygems_version: 1.8.23