cql-rb 1.1.0.pre8 → 1.1.0.rc0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/README.md +45 -25
- data/lib/cql/client.rb +86 -37
- data/lib/cql/client/asynchronous_client.rb +4 -9
- data/lib/cql/version.rb +1 -1
- data/spec/cql/client/asynchronous_client_spec.rb +6 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MTBkMThlZTE2MTk5MzFiNTgzNmYyMDM4ZTViNjNhNjFhNWM3OGVhNw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZWQ1M2EzZWExOGUyNzUwNzE2ODQxMzgyYmI2MDdkM2ZhY2Q0NTA3OQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
Y2QzMzNmMTg1ODZhYzVmYTU4Njk5MjYzNDgxZmFlMjExZTYwYzRiNjk2MjVj
|
10
|
+
YmYxOWQ3YzVkNDZlNmM5NWQ2YzYwN2Y5OGMwMDc1NWYzZTBhMzBhZmRlZGU2
|
11
|
+
ODUwMGY4NGIxNTdlNWVlZThlZTc4M2NhZjU4ODVlMGYyYWM5MWM=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YzQ1ZTRjMjUxM2I4OGJlMGRkZDE4NTkwZmZkNWFmZjc5NTNhNWI2ZmNjZTZi
|
14
|
+
YjE2ZGM0ODIzMDBmNmViNzBjMDU5YzUzZDVkNGNjMTQyMzYzY2FjNDdkYTAx
|
15
|
+
OGQ4ODIwZDk5YzQ4YjRmOGUxMmYzZTcyNmVlMTcwM2VlNWE5ZjQ=
|
data/README.md
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
|
6
6
|
# Requirements
|
7
7
|
|
8
|
-
Cassandra 1.2 with the native transport protocol turned on and a modern Ruby. It's tested continuously in Travis with Ruby 1.9.3, 2.0.0, and JRuby 1.7.x stable and head.
|
8
|
+
Cassandra 1.2 or later with the native transport protocol turned on and a modern Ruby. It's tested continuously in Travis with Ruby 1.9.3, 2.0.0, and JRuby 1.7.x stable and head.
|
9
9
|
|
10
10
|
# Installation
|
11
11
|
|
@@ -13,14 +13,14 @@ Cassandra 1.2 with the native transport protocol turned on and a modern Ruby. It
|
|
13
13
|
|
14
14
|
## Configure Cassandra
|
15
15
|
|
16
|
-
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`.
|
16
|
+
If you're running Cassandra 1.2.5 or later 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`.
|
17
17
|
|
18
18
|
# Quick start
|
19
19
|
|
20
20
|
```ruby
|
21
21
|
require 'cql'
|
22
22
|
|
23
|
-
client = Cql::Client.connect(
|
23
|
+
client = Cql::Client.connect(hosts: ['cassandra.example.com'])
|
24
24
|
client.use('system')
|
25
25
|
rows = client.execute('SELECT keyspace_name, columnfamily_name FROM schema_columnfamilies')
|
26
26
|
rows.each do |row|
|
@@ -28,7 +28,13 @@ rows.each do |row|
|
|
28
28
|
end
|
29
29
|
```
|
30
30
|
|
31
|
-
|
31
|
+
The host you specify is just a seed node, the client will automatically connect to all other nodes in the cluster (or nodes in the same data center if you're running multiple rings).
|
32
|
+
|
33
|
+
When you're done you can call `#close` to disconnect from Cassandra:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
client.close
|
37
|
+
```
|
32
38
|
|
33
39
|
# Usage
|
34
40
|
|
@@ -74,6 +80,8 @@ rows = client.execute('SELECT date, description FROM events'
|
|
74
80
|
rows.metadata['date'].type # => :date
|
75
81
|
```
|
76
82
|
|
83
|
+
Each call to `#execute` selects a random connection to run the query on.
|
84
|
+
|
77
85
|
## Creating keyspaces and tables
|
78
86
|
|
79
87
|
There is no special facility for creating keyspaces and tables, they are created by executing CQL:
|
@@ -97,11 +105,11 @@ table_definition = <<-TABLEDEF
|
|
97
105
|
TABLEDEF
|
98
106
|
|
99
107
|
client.execute(keyspace_definition)
|
100
|
-
client.use(measurements)
|
108
|
+
client.use('measurements')
|
101
109
|
client.execute(table_definition)
|
102
110
|
```
|
103
111
|
|
104
|
-
You can also `ALTER` keyspaces and tables.
|
112
|
+
You can also `ALTER` keyspaces and tables, and you can read more about that in the [CQL3 syntax documentation](https://github.com/apache/cassandra/blob/cassandra-1.2/doc/cql3/CQL.textile).
|
105
113
|
|
106
114
|
## Prepared statements
|
107
115
|
|
@@ -116,17 +124,29 @@ A prepared statement can be run many times, but the CQL parsing will only be don
|
|
116
124
|
|
117
125
|
`INSERT`, `UPDATE`, `DELETE` and `SELECT` statements can be prepared, other statements may raise `QueryError`.
|
118
126
|
|
119
|
-
|
127
|
+
Statements are prepared on all connections and each call to `#execute` selects a random connection to run the query on.
|
120
128
|
|
121
|
-
|
129
|
+
## Consistency
|
122
130
|
|
123
|
-
|
131
|
+
You can specify the default consistency to use when you create a new `Client`:
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
client = Cql::Client.connect(hosts: %w[localhost], consistency: :all)
|
135
|
+
```
|
136
|
+
|
137
|
+
The `#execute` (of `Client` and `PreparedStatement`) method also supports setting the desired consistency level on a per-request basis:
|
138
|
+
|
139
|
+
```ruby
|
140
|
+
client.execute('SELECT * FROM peers', consistency: :local_quorum)
|
141
|
+
```
|
142
|
+
|
143
|
+
for backwards compatibility with v1.0 you can also pass the consistency as just a symbol:
|
124
144
|
|
125
145
|
```ruby
|
126
146
|
client.execute('SELECT * FROM peers', :local_quorum)
|
127
147
|
```
|
128
148
|
|
129
|
-
The possible values are:
|
149
|
+
The possible values for consistency are:
|
130
150
|
|
131
151
|
* `:any`
|
132
152
|
* `:one`
|
@@ -137,16 +157,20 @@ The possible values are:
|
|
137
157
|
* `:local_quorum`
|
138
158
|
* `:each_quorum`
|
139
159
|
|
140
|
-
The default consistency level is `:quorum`.
|
160
|
+
The default consistency level unless you've set it yourself is `:quorum`.
|
141
161
|
|
142
162
|
Consistency is ignored for `USE`, `TRUNCATE`, `CREATE` and `ALTER` statements, and some (like `:any`) aren't allowed in all situations.
|
143
163
|
|
144
|
-
|
164
|
+
# CQL3
|
145
165
|
|
146
166
|
This is just a driver for the Cassandra native CQL protocol, it doesn't really know anything about CQL. You can run any CQL3 statement and the driver will return whatever Cassandra replies with.
|
147
167
|
|
148
168
|
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).
|
149
169
|
|
170
|
+
# Cassandra 2.0
|
171
|
+
|
172
|
+
Cassandra 2.0 introduced a new version of the native protocol with some new features like argument interpolation in non-prepared statements, result set cursors, a new authentication mechanism and the `SERIAL` consistency. These features are not yet supported, but the driver will work with Cassandra 2.0 using the earlier protocol.
|
173
|
+
|
150
174
|
# Troubleshooting
|
151
175
|
|
152
176
|
## I get "Deadlock detected" errors
|
@@ -185,10 +209,6 @@ If your process does not fork and you still encounter deadlock errors, it might
|
|
185
209
|
|
186
210
|
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.
|
187
211
|
|
188
|
-
## The error backtraces are weird
|
189
|
-
|
190
|
-
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.
|
191
|
-
|
192
212
|
## Authentication doesn't work
|
193
213
|
|
194
214
|
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.
|
@@ -197,10 +217,6 @@ Please open an issue. It should be working, but it's hard to write tests for, so
|
|
197
217
|
|
198
218
|
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.
|
199
219
|
|
200
|
-
## One of my Cassandra nodes crashed, and my application crashed, isn't Cassandra supposed to be fault tolerant?
|
201
|
-
|
202
|
-
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. _This is fixed in HEAD and will be released with v1.1.0_.
|
203
|
-
|
204
220
|
## Something else is not working
|
205
221
|
|
206
222
|
Open an issue and someone will try to help you out. 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. The more information you give, the better the chances you will get help.
|
@@ -209,16 +225,20 @@ Open an issue and someone will try to help you out. Please include the gem versi
|
|
209
225
|
|
210
226
|
Check out the [releases on GitHub](https://github.com/iconara/cql-rb/releases). Version numbering follows the [semantic versioning](http://semver.org/) scheme.
|
211
227
|
|
228
|
+
Private and experimental APIs, defined as whatever is not in the [public API documentation](http://rubydoc.info/gems/cql-rb/frames) will change without warning. If you've been recommended to try an experimental API by the maintainers, please let them know if you depend on that API. Experimental APIs will eventually become public, and knowing how they are used helps in determining their maturity.
|
229
|
+
|
230
|
+
Prereleases will be stable, in the sense that they will have finished and properly tested features only, but may introduce APIs that will change before the final release. Please use the prereleases and report bugs, but don't deploy them to production without consulting the maintainers, or doing extensive testing yourself. If you do deploy to production please let the maintainers know as this helps determining the maturity of the release.
|
231
|
+
|
212
232
|
# Known bugs & limitations
|
213
233
|
|
214
|
-
* No automatic peer discovery -- _this is in HEAD and will be released with v1.1.0_.
|
215
|
-
* No automatic reconnection on connection failures -- _this is in HEAD and will be released with v1.1.0_.
|
216
|
-
* No support for request timeouts (other than server-initiated), but requests to a node fail when that node goes down -- _this is in HEAD and will be released with v1.1.0_.
|
217
234
|
* No support for compression.
|
218
235
|
* No support for request tracing.
|
219
|
-
* JRuby 1.6
|
236
|
+
* JRuby 1.6 is not officially supported, although 1.6.8 should work, if you're stuck in JRuby 1.6.8 try and see if it works for you.
|
220
237
|
* 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.
|
221
238
|
* There is no cluster introspection utilities (like the `DESCRIBE` commands in `cqlsh`).
|
239
|
+
* New features in v2 of the protocol are not supported
|
240
|
+
|
241
|
+
Also check out the [issues](https://github.com/iconara/cql-rb/issues) for open bugs.
|
222
242
|
|
223
243
|
# How to contribute
|
224
244
|
|
@@ -234,7 +254,7 @@ Always remember that the maintainers' work on this project in their free time an
|
|
234
254
|
|
235
255
|
# Copyright
|
236
256
|
|
237
|
-
Copyright 2013 Theo Hultberg/Iconara
|
257
|
+
Copyright 2013 Theo Hultberg/Iconara and contributors
|
238
258
|
|
239
259
|
_Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License You may obtain a copy of the License at_
|
240
260
|
|
data/lib/cql/client.rb
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
module Cql
|
4
|
+
# This error type represents errors sent by the server, the `code` attribute
|
5
|
+
# can be used to find the exact type, and `cql` contains the request's CQL,
|
6
|
+
# if any. `message` contains the human readable error message sent by the
|
7
|
+
# server.
|
4
8
|
class QueryError < CqlError
|
5
9
|
attr_reader :code, :cql
|
6
10
|
|
@@ -19,9 +23,14 @@ module Cql
|
|
19
23
|
# A CQL client manages connections to one or more Cassandra nodes and you use
|
20
24
|
# it run queries, insert and update data.
|
21
25
|
#
|
26
|
+
# Client instances are threadsafe.
|
27
|
+
#
|
28
|
+
# See {Cql::Client::Client} for the full client API, or {Cql::Client.connect}
|
29
|
+
# for the options available when connecting.
|
30
|
+
#
|
22
31
|
# @example Connecting and changing to a keyspace
|
23
32
|
# # create a client and connect to two Cassandra nodes
|
24
|
-
# client = Cql::Client.connect(
|
33
|
+
# client = Cql::Client.connect(hosts: %w[node01.cassandra.local node02.cassandra.local])
|
25
34
|
# # change to a keyspace
|
26
35
|
# client.use('stuff')
|
27
36
|
#
|
@@ -39,11 +48,6 @@ module Cql
|
|
39
48
|
# statement = client.prepare('INSERT INTO things (id, value) VALUES (?, ?)')
|
40
49
|
# statement.execute(9, 'qux')
|
41
50
|
# statement.execute(8, 'baz')
|
42
|
-
#
|
43
|
-
# Client instances are threadsafe.
|
44
|
-
#
|
45
|
-
# See {Cql::Client::Client} for the full client API.
|
46
|
-
#
|
47
51
|
module Client
|
48
52
|
InvalidKeyspaceNameError = Class.new(ClientError)
|
49
53
|
|
@@ -54,25 +58,43 @@ module Cql
|
|
54
58
|
# connected to the hosts given in `:hosts` the rest of the nodes in the
|
55
59
|
# cluster will automatically be discovered and connected to.
|
56
60
|
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
61
|
+
# If you have a multi data center setup the client will connect to all nodes
|
62
|
+
# in the data centers where the nodes you pass to `:hosts` are located. So
|
63
|
+
# if you only want to connect to nodes in one data center, make sure that
|
64
|
+
# you only specify nodes in that data center in `:hosts`.
|
65
|
+
#
|
66
|
+
# The connection will succeed if at least one node is up and accepts the
|
67
|
+
# connection. Nodes that don't respond within the specified timeout, or
|
68
|
+
# where the connection initialization fails for some reason, are ignored.
|
60
69
|
#
|
61
|
-
# @raise Cql::Io::ConnectionError when a connection couldn't be established
|
62
|
-
# to any node
|
63
70
|
# @param [Hash] options
|
64
71
|
# @option options [Array<String>] :hosts (['localhost']) One or more
|
65
72
|
# hostnames used as seed nodes when connecting. Duplicates will be removed.
|
66
73
|
# @option options [String] :host ('localhost') A comma separated list of
|
67
74
|
# hostnames to use as seed nodes. This is a backwards-compatible version
|
68
75
|
# of the :hosts option, and is deprecated.
|
69
|
-
# @option options [String] :port (9042) The port to connect to
|
76
|
+
# @option options [String] :port (9042) The port to connect to, this port
|
77
|
+
# will be used for all nodes. Because the `system.peers` table does not
|
78
|
+
# contain the port that the nodes are listening on, the port must be the
|
79
|
+
# same for all nodes.
|
70
80
|
# @option options [Integer] :connection_timeout (5) Max time to wait for a
|
71
|
-
# connection, in seconds
|
81
|
+
# connection, in seconds.
|
72
82
|
# @option options [String] :keyspace The keyspace to change to immediately
|
73
83
|
# after all connections have been established, this is optional.
|
84
|
+
# @option options [Integer] :connections_per_node (1) The number of
|
85
|
+
# connections to open to each node. Each connection can have 128
|
86
|
+
# concurrent requests, so unless you have a need for more than that (times
|
87
|
+
# the number of nodes in your cluster), leave this option at its default.
|
88
|
+
# @option options [Integer] :default_consistency (:quorum) The consistency
|
89
|
+
# to use unless otherwise specified. Consistency can also be specified on
|
90
|
+
# a per-request basis.
|
91
|
+
# @option options [Integer] :logger If you want the client to log
|
92
|
+
# significant events pass an object implementing the standard Ruby logger
|
93
|
+
# interface (e.g. quacks like `Logger` from the standard library) with
|
94
|
+
# this option.
|
95
|
+
# @raise Cql::Io::ConnectionError when a connection couldn't be established
|
96
|
+
# to any node
|
74
97
|
# @return [Cql::Client::Client]
|
75
|
-
#
|
76
98
|
def self.connect(options={})
|
77
99
|
SynchronousClient.new(AsynchronousClient.new(options)).connect
|
78
100
|
end
|
@@ -80,13 +102,13 @@ module Cql
|
|
80
102
|
class Client
|
81
103
|
# @!method connect
|
82
104
|
#
|
83
|
-
# Connect to all nodes.
|
105
|
+
# Connect to all nodes. See {Cql::Client.connect} for the full
|
106
|
+
# documentation.
|
84
107
|
#
|
85
|
-
#
|
86
|
-
#
|
108
|
+
# This method needs to be called before any other. Calling it again will
|
109
|
+
# have no effect.
|
87
110
|
#
|
88
111
|
# @see Cql::Client.connect
|
89
|
-
#
|
90
112
|
# @return [Cql::Client]
|
91
113
|
|
92
114
|
# @!method close
|
@@ -118,17 +140,26 @@ module Cql
|
|
118
140
|
# @raise [Cql::NotConnectedError] raised when the client is not connected
|
119
141
|
# @return [nil]
|
120
142
|
|
121
|
-
# @!method execute(cql,
|
143
|
+
# @!method execute(cql, options_or_consistency=nil)
|
122
144
|
#
|
123
145
|
# Execute a CQL statement
|
124
146
|
#
|
125
147
|
# @param [String] cql
|
126
|
-
# @param [
|
148
|
+
# @param [Hash] options_or_consistency Either a consistency as a symbol
|
149
|
+
# (e.g. `:quorum`), or a options hash (see below). Passing a symbol is
|
150
|
+
# equivalent to passing the options `consistency: <symbol>`.
|
151
|
+
# @option options_or_consistency [Symbol] :consistency (:quorum) The
|
152
|
+
# consistency to use for this query.
|
153
|
+
# @option options_or_consistency [Symbol] :timeout (nil) How long to wait
|
154
|
+
# for a response. If this timeout expires a {Cql::TimeoutError} will
|
155
|
+
# be raised.
|
127
156
|
# @raise [Cql::NotConnectedError] raised when the client is not connected
|
157
|
+
# @raise [Cql::TimeoutError] raised when a timeout was specified and no
|
158
|
+
# response was received within the timeout.
|
128
159
|
# @raise [Cql::QueryError] raised when the CQL has syntax errors or for
|
129
160
|
# other situations when the server complains.
|
130
|
-
# @return [nil, Cql::Client::QueryResult] Most
|
131
|
-
# `nil`, but `SELECT` statements return an `Enumerable` of rows
|
161
|
+
# @return [nil, Cql::Client::QueryResult] Most queries have no result and
|
162
|
+
# return `nil`, but `SELECT` statements return an `Enumerable` of rows
|
132
163
|
# (see {Cql::Client::QueryResult}).
|
133
164
|
|
134
165
|
# @!method prepare(cql)
|
@@ -136,30 +167,48 @@ module Cql
|
|
136
167
|
# Returns a prepared statement that can be run over and over again with
|
137
168
|
# different values.
|
138
169
|
#
|
139
|
-
# @
|
170
|
+
# @see Cql::Client::PreparedStatement
|
171
|
+
# @param [String] cql The CQL to prepare
|
140
172
|
# @raise [Cql::NotConnectedError] raised when the client is not connected
|
141
|
-
# @
|
173
|
+
# @raise [Cql::Io::IoError] raised when there is an IO error, for example
|
174
|
+
# if the server suddenly closes the connection
|
175
|
+
# @raise [Cql::QueryError] raised when there is an error on the server
|
176
|
+
# side, for example when you specify a malformed CQL query
|
177
|
+
# @return [Cql::Client::PreparedStatement] an object encapsulating the
|
178
|
+
# prepared statement
|
142
179
|
end
|
143
180
|
|
144
181
|
class PreparedStatement
|
145
182
|
# @return [ResultMetadata]
|
146
183
|
attr_reader :metadata
|
147
184
|
|
148
|
-
# Execute the prepared statement with a list of values
|
149
|
-
#
|
150
|
-
#
|
151
|
-
#
|
152
|
-
#
|
153
|
-
#
|
154
|
-
#
|
155
|
-
#
|
156
|
-
#
|
157
|
-
#
|
185
|
+
# Execute the prepared statement with a list of values to be bound to the
|
186
|
+
# statements parameters.
|
187
|
+
#
|
188
|
+
# The number of arguments must equal the number of bound parameters. You
|
189
|
+
# can also specify options as the last argument, or a symbol as a shortcut
|
190
|
+
# for just specifying the consistency.
|
191
|
+
#
|
192
|
+
# Because you can specify options, or not, there is an edge case where if
|
193
|
+
# the last parameter of your prepared statement is a map, and you forget
|
194
|
+
# to specify a value for your map, the options will end up being sent to
|
195
|
+
# Cassandra. Most other cases when you specify the wrong number of
|
196
|
+
# arguments should result in an `ArgumentError` or `TypeError` being
|
197
|
+
# raised.
|
198
|
+
#
|
199
|
+
# @param args [Array] the values for the bound parameters. The last
|
200
|
+
# argument can also be an options hash or a symbol (as a shortcut for
|
201
|
+
# specifying the consistency), see {Cql::Client::Client#execute} for
|
202
|
+
# full details.
|
203
|
+
# @raise [ArgumentError] raised when number of argument does not match
|
204
|
+
# the number of parameters needed to be bound to the statement.
|
158
205
|
# @raise [Cql::NotConnectedError] raised when the client is not connected
|
206
|
+
# @raise [Cql::Io::IoError] raised when there is an IO error, for example
|
207
|
+
# if the server suddenly closes the connection
|
159
208
|
# @raise [Cql::QueryError] raised when there is an error on the server side
|
160
|
-
# @return [nil, Cql::Client::QueryResult] Most statements have no result
|
161
|
-
#
|
162
|
-
# (see {Cql::Client::QueryResult}).
|
209
|
+
# @return [nil, Cql::Client::QueryResult] Most statements have no result
|
210
|
+
# and return `nil`, but `SELECT` statements return an `Enumerable` of
|
211
|
+
# rows (see {Cql::Client::QueryResult}).
|
163
212
|
def execute(*args)
|
164
213
|
end
|
165
214
|
end
|
@@ -27,22 +27,16 @@ module Cql
|
|
27
27
|
|
28
28
|
def connect
|
29
29
|
@lock.synchronize do
|
30
|
+
raise ClientError, 'Cannot connect a closed client' if @closing || @closed
|
30
31
|
return @connected_future if can_execute?
|
31
32
|
@connecting = true
|
32
33
|
@connected_future = begin
|
33
34
|
f = @connection_helper.connect(@hosts, @initial_keyspace)
|
34
|
-
|
35
|
-
ff = @closed_future
|
36
|
-
ff = ff.flat_map { f }
|
37
|
-
ff = ff.fallback { f }
|
38
|
-
else
|
39
|
-
ff = f
|
40
|
-
end
|
41
|
-
ff.on_value do |connections|
|
35
|
+
f.on_value do |connections|
|
42
36
|
@connection_manager.add_connections(connections)
|
43
37
|
register_event_listener(@connection_manager.random_connection)
|
44
38
|
end
|
45
|
-
|
39
|
+
f.map { self }
|
46
40
|
end
|
47
41
|
end
|
48
42
|
@connected_future.on_complete(&method(:connected))
|
@@ -140,6 +134,7 @@ module Cql
|
|
140
134
|
def closed(f)
|
141
135
|
@lock.synchronize do
|
142
136
|
@closing = false
|
137
|
+
@closed = true
|
143
138
|
@connected = false
|
144
139
|
if f.resolved?
|
145
140
|
@logger.info('Cluster disconnect complete')
|
data/lib/cql/version.rb
CHANGED
@@ -400,6 +400,12 @@ module Cql
|
|
400
400
|
io_reactor.stub(:stop).and_return(Future.failed(StandardError.new('Bork!')))
|
401
401
|
expect { client.close.value }.to raise_error('Bork!')
|
402
402
|
end
|
403
|
+
|
404
|
+
it 'cannot be connected again once closed' do
|
405
|
+
client.connect.value
|
406
|
+
client.close.value
|
407
|
+
expect { client.connect.value }.to raise_error(ClientError)
|
408
|
+
end
|
403
409
|
end
|
404
410
|
|
405
411
|
describe '#use' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cql-rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.0.
|
4
|
+
version: 1.1.0.rc0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Theo Hultberg
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-10-
|
11
|
+
date: 2013-10-17 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: A pure Ruby CQL3 driver for Cassandra
|
14
14
|
email:
|