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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- OTcyZDFmZGEzMGZhODU2MTRkYmRlMjhiNWIyYWI0OWVkODZmYmY3Mg==
4
+ ODg3NTI1OTYyMmViMzc5OWU4YjQyYTViYmQyMDFmZmNjOTIzMGExNg==
5
5
  data.tar.gz: !binary |-
6
- MzQ5Y2M4YmI1YzQ3Yjk3MDU4YzI1YWJjYmZjYTc2YTE4NjA4ZTRmMQ==
6
+ NjI3OWQyZDc0NTM1MmE4M2VlMWVhM2EwMTRlMGVjYzdjODQyOGIzNw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- NmFiNzc1M2E0NTk0YmIyY2VjNTcxZjI2ZDcwMGE5NmUzZDhhZGU5NmYyMTRj
10
- M2NiZjgwNzdmMzJjOTA4YzBjNjVlYjRlNmJmZjE3MjZhOWY1ODRlOTQwM2Qy
11
- YzYyNzc2MTFmYzNjOWNiZmI4NjY3Yjg4ZjBjYjJkMWRmMTY2Mzg=
9
+ ZGFhMWZjYWUyMTdlYzllODBmNGVjMTkzZjU5YWYyN2M3MjQwZmVhNTI3NzIz
10
+ ZGFiYTA3NzAyNWU0MWQ4Njg1OWFhNTViNTQ0NDFmMDU4NmQwMWQ3OTFkNjBj
11
+ NTdlM2ZjOTAwYTA5Njk4ZWQ2Nzk3ZjQ1OWM1MWU5YzcyODcwZmY=
12
12
  data.tar.gz: !binary |-
13
- M2EzNzFhZDM5MTNkMTlhNzVhZTE1YzdmZGMyMWEyY2ZmZTc4N2YwMGIwMjll
14
- ODhkNzFjODE3NmMxYTE5Y2U4MzA0ZjViMTQ3MzYyMjcwZDJkNjgyZjg1Y2Q2
15
- NWY3MjRjM2QwY2VhMTU4MGIzOWM0YmY2MjI4ZmYyOTdhMDU0NDE=
13
+ YTQ0MDg5ZjI3Yzg5MGRiOGI1YTdlMjgwZGIxZjI1Y2ZkZDVhZWYwOGFkYTJi
14
+ MzIyOTY1OTY1ODgzMjhkYWY2ODYxYTIzZTRiYzI5OWRjODIwN2FmM2FlYTVk
15
+ YWFjOGNkMjY3OGJhYjhjZmE5ODMzMzgzMGNjNGU5ZmMyZTllYWI=
data/README.md CHANGED
@@ -16,22 +16,29 @@ the Cassandra Query Language version 3 (CQL3) and Cassandra's native protocol.
16
16
 
17
17
  This driver is based on [the cql-rb gem](https://github.com/iconara/cql-rb) by [Theo Hultberg](https://github.com/iconara) and we added support for:
18
18
 
19
- * [asynchronous execution](http://datastax.github.io/ruby-driver/features/asynchronous_io/)
20
- * one-off, [prepared](http://datastax.github.io/ruby-driver/features/basics/prepared_statements/) and [batch statements](http://datastax.github.io/ruby-driver/features/basics/batch_statements/)
21
- * automatic peer discovery and cluster metadata
22
- * various [load-balancing](http://datastax.github.io/ruby-driver/features/load_balancing/), [retry](http://datastax.github.io/ruby-driver/features/retry_policies/) and reconnection policies, [with ability to write your own](http://datastax.github.io/ruby-driver/features/load_balancing/implementing_a_policy/)
19
+ * [Asynchronous execution](http://datastax.github.io/ruby-driver/features/asynchronous_io/)
20
+ * One-off, [prepared](http://datastax.github.io/ruby-driver/features/basics/prepared_statements/) and [batch statements](http://datastax.github.io/ruby-driver/features/basics/batch_statements/)
21
+ * Automatic peer discovery and cluster metadata with [support for change notifications](http://datastax.github.io/ruby-driver/features/state_listeners/)
22
+ * Various [load-balancing](http://datastax.github.io/ruby-driver/features/load_balancing/), [retry](http://datastax.github.io/ruby-driver/features/retry_policies/) and [reconnection](http://datastax.github.io/ruby-driver/features/reconnection/) policies with [ability to write your own](http://datastax.github.io/ruby-driver/features/load_balancing/implementing_a_policy/)
23
23
  * [SSL encryption](http://datastax.github.io/ruby-driver/features/security/ssl_encryption/)
24
+ * [Flexible and robust error handling](http://datastax.github.io/ruby-driver/features/error_handling/)
25
+ * [Per-request execution information and tracing](http://datastax.github.io/ruby-driver/features/debugging/)
26
+ * [Configurable address resolution](http://datastax.github.io/ruby-driver/features/address_resolution/)
27
+
28
+ [Check out the slides from Ruby Driver Explained](https://speakerdeck.com/avalanche123/ruby-driver-explained) for a detailed overview of the Ruby Driver architecture.
24
29
 
25
30
  ## Compability
26
31
 
27
32
  This driver works exclusively with the Cassandra Query Language v3 (CQL3) and Cassandra's native protocol. The current version works with:
28
33
 
29
- * Apache Cassandra versions 1.2 and 2.0
34
+ * Apache Cassandra versions 1.2, 2.0 and partially 2.1
30
35
  * DataStax Enterprise 3.1, 3.2, 4.0 and 4.5
31
36
  * Ruby (MRI) 1.9.3, 2.0 and 2.1
32
37
  * JRuby 1.7
33
38
  * Rubinius 2.2
34
39
 
40
+ __Note__: Apache Cassandra 2.1 support is limited to the Cassandra 2.0 API, e.g. no user-defined types.
41
+
35
42
  __Note__: JRuby 1.6 is not officially supported, although 1.6.8 should work.
36
43
 
37
44
  ## Quick start
@@ -57,7 +64,7 @@ end
57
64
  future.join
58
65
  ```
59
66
 
60
- The host you specify is just a seed node, the driver will automatically discover all peers in the cluster.
67
+ __Note__: The host you specify is just a seed node, the driver will automatically discover all peers in the cluster.
61
68
 
62
69
  Read more:
63
70
 
@@ -70,34 +77,32 @@ Read more:
70
77
  Install via rubygems
71
78
 
72
79
  ```bash
73
- gem install cassandra-driver --pre
80
+ gem install cassandra-driver
74
81
  ```
75
82
 
76
83
  Install via Gemfile
77
84
 
78
85
  ```ruby
79
- gem 'cassandra-driver', '~> 1.0.0.rc'
86
+ gem 'cassandra-driver', '~> 1.0.0'
80
87
  ```
81
88
 
82
- Note: if you want to use compression you should also install [snappy](http://rubygems.org/gems/snappy) or [lz4-ruby](http://rubygems.org/gems/lz4-ruby). [Read more about compression.](http://datastax.github.io/ruby-driver/features/#compression)
89
+ __Note__: if you want to use compression you should also install [snappy](http://rubygems.org/gems/snappy) or [lz4-ruby](http://rubygems.org/gems/lz4-ruby). [Read more about compression.](http://datastax.github.io/ruby-driver/features/#compression)
83
90
 
84
91
 
85
92
  ## Upgrading from cql-rb
86
93
 
87
94
  Some of the new features added to the driver have unfortunately led to changes in the original cql-rb API. In the examples directory, you can find [an example of how to wrap the ruby driver to achieve almost complete interface parity with cql-rb](https://github.com/datastax/ruby-driver/blob/master/examples/cql-rb-wrapper.rb) to assist you with gradual upgrade.
88
95
 
89
- ## What's new in v1.0.0
96
+ ## What's new in v1.1.0
90
97
 
91
98
  Current release introduces the following new features:
92
99
 
93
- * [Asynchronous execution](http://datastax.github.io/ruby-driver/features/asynchronous_io/)
94
- * One-off, [prepared](http://datastax.github.io/ruby-driver/features/basics/prepared_statements/) and [batch statements](http://datastax.github.io/ruby-driver/features/basics/batch_statements/)
95
- * Automatic peer discovery and cluster metadata with [support for change notifications](http://datastax.github.io/ruby-driver/features/state_listeners/)
96
- * Various [load-balancing](http://datastax.github.io/ruby-driver/features/load_balancing/), [retry](http://datastax.github.io/ruby-driver/features/retry_policies/) and reconnection policies, [with ability to write your own](http://datastax.github.io/ruby-driver/features/load_balancing/implementing_a_policy/)
97
- * [SSL encryption](http://datastax.github.io/ruby-driver/features/security/ssl_encryption/)
98
- * [Flexible and robust error handling](http://datastax.github.io/ruby-driver/features/error_handling/)
99
- * [Per-request execution information and tracing](http://datastax.github.io/ruby-driver/features/debugging/)
100
- * [Configurable address resolution](http://datastax.github.io/ruby-driver/features/address_resolution/)
100
+ * Ability to disable automatic schema synchronization
101
+ * Schema change event storm protection using a sliding delay
102
+ * [`Cassandra::LoadBalancing::Policy#teardown`](http://datastax.github.io/ruby-driver/api/load_balancing/policy/#teardown-instance_method) for cleaning up resources
103
+ * [`Cassandra::Cluster#refresh_schema`](http://datastax.github.io/ruby-driver/api/cluster/#refresh_schema-instance_method) for manually refreshing schema metadata
104
+ * Host list randomization to prevent hotspots between multiple clients
105
+ * Future listeners run in a dedicated threadpool to not block the reactor
101
106
 
102
107
  ## Code examples
103
108
 
data/lib/cassandra.rb CHANGED
@@ -25,7 +25,6 @@ require 'ipaddr'
25
25
  require 'set'
26
26
  require 'bigdecimal'
27
27
  require 'forwardable'
28
- require 'timeout'
29
28
  require 'digest'
30
29
  require 'stringio'
31
30
  require 'resolv'
@@ -51,7 +50,7 @@ module Cassandra
51
50
  # @see https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v1.spec#L591-L603 Description of possible types of writes in Apache Cassandra native protocol spec v1
52
51
  WRITE_TYPES = [:simple, :batch, :unlogged_batch, :counter, :batch_log].freeze
53
52
 
54
- # Creates a {Cassandra::Cluster} instance
53
+ # Creates a {Cassandra::Cluster Cluster instance}.
55
54
  #
56
55
  # @option options [Array<String, IPAddr>] :hosts (['127.0.0.1']) a list of
57
56
  # initial addresses. Note that the entire list of cluster members will be
@@ -65,6 +64,10 @@ module Cassandra
65
64
  # can skip this option if you specify only hosts from the local datacenter
66
65
  # in `:hosts` option.
67
66
  #
67
+ # @option options [Boolean] :shuffle_replicas (true) whether replicas list
68
+ # found by the default Token-Aware Load Balancing Policy should be
69
+ # shuffled. See {Cassandra::LoadBalancing::Policies::TokenAware#initialize Token-Aware Load Balancing Policy}.
70
+ #
68
71
  # @option options [Numeric] :connect_timeout (10) connection timeout in
69
72
  # seconds. Setting value to `nil` will reset it to 5 seconds.
70
73
  #
@@ -119,12 +122,33 @@ module Cassandra
119
122
  # address resolver to use. Must be one of `:none` or
120
123
  # `:ec2_multi_region`.
121
124
  #
125
+ # @option options [Boolean] :synchronize_schema (true) whether the driver
126
+ # should automatically keep schema metadata synchronized. When enabled, the
127
+ # driver updates schema metadata after receiving schema change
128
+ # notifications from Cassandra. Setting this setting to `false` disables
129
+ # automatic schema updates. Schema metadata is used by the driver to
130
+ # determine cluster partitioners as well as to find partition keys and
131
+ # replicas of prepared statements, this information makes token aware load
132
+ # balancing possible. One can still {Cassandra::Cluster#refresh_schema refresh schema manually}.
133
+ #
134
+ # @option options [Numeric] :schema_refresh_delay (1) the driver will wait
135
+ # for `:schema_refresh_delay` before fetching metadata after receiving a
136
+ # schema change event. This timer is restarted every time a new schema
137
+ # change event is received. Finally, when the timer expires or a maximum
138
+ # wait time of `:schema_refresh_timeout` has been reached, a schema refresh
139
+ # attempt will be made and the timeout is reset.
140
+ #
141
+ # @option options [Numeric] :schema_refresh_timeout (10) the maximum delay
142
+ # before automatically refreshing schema. Such delay can occur whenever
143
+ # multiple schema change events are continuously arriving within
144
+ # `:schema_refresh_delay` interval.
145
+ #
122
146
  # @option options [Cassandra::Reconnection::Policy] :reconnection_policy
123
- # default: {Cassandra::Reconnection::Policies::Exponential}. Note that the
124
- # default policy is configured with `(0.5, 30, 2)`.
147
+ # default: {Cassandra::Reconnection::Policies::Exponential Exponential}.
148
+ # Note that the default policy is configured with `(0.5, 30, 2)`.
125
149
  #
126
150
  # @option options [Cassandra::Retry::Policy] :retry_policy default:
127
- # {Cassandra::Retry::Policies::Default}.
151
+ # {Cassandra::Retry::Policies::Default Default Retry Policy}.
128
152
  #
129
153
  # @option options [Logger] :logger (none) logger. a {Logger} instance from the
130
154
  # standard library or any object responding to standard log methods
@@ -145,7 +169,7 @@ module Cassandra
145
169
  #
146
170
  # @option options [Hash{String => String}] :credentials (none) a hash of credentials - to be used with [credentials authentication in cassandra 1.2](https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v1.spec#L238-L250). Note that if you specified `:username` and `:password` options, those credentials are configured automatically.
147
171
  #
148
- # @option options [Cassandra::Auth::Provider] :auth_provider (none) a custom auth provider to be used with [SASL authentication in cassandra 2.0](https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v2.spec#L257-L273). Note that if you have specified `:username` and `:password`, then a {Cassandra::Auth::Providers::Password} will be used automatically.
172
+ # @option options [Cassandra::Auth::Provider] :auth_provider (none) a custom auth provider to be used with [SASL authentication in cassandra 2.0](https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v2.spec#L257-L273). Note that if you have specified `:username` and `:password`, then a {Cassandra::Auth::Providers::Password Password Provider} will be used automatically.
149
173
  #
150
174
  # @option options [Cassandra::Compression::Compressor] :compressor (none) a
151
175
  # custom compressor. Note that if you have specified `:compression`, an
@@ -153,7 +177,7 @@ module Cassandra
153
177
  #
154
178
  # @option options [Cassandra::AddressResolution::Policy]
155
179
  # :address_resolution_policy default:
156
- # {Cassandra::AddressResolution::Policies::None} a custom address resolution
180
+ # {Cassandra::AddressResolution::Policies::None No Resolution Policy} a custom address resolution
157
181
  # policy. Note that if you have specified `:address_resolution`, an
158
182
  # appropriate address resolution policy will be provided automatically.
159
183
  #
@@ -178,7 +202,7 @@ module Cassandra
178
202
  cluster_async(options).get
179
203
  end
180
204
 
181
- # Creates a {Cassandra::Cluster} instance
205
+ # Creates a {Cassandra::Cluster Cluster instance}.
182
206
  #
183
207
  # @see Cassandra.cluster
184
208
  #
@@ -191,12 +215,12 @@ module Cassandra
191
215
  :consistency, :trace, :page_size, :compressor, :username, :password,
192
216
  :ssl, :server_cert, :client_cert, :private_key, :passphrase,
193
217
  :connect_timeout, :futures_factory, :datacenter, :address_resolution,
194
- :address_resolution_policy, :idle_timeout, :heartbeat_interval, :timeout
218
+ :address_resolution_policy, :idle_timeout, :heartbeat_interval, :timeout,
219
+ :synchronize_schema, :schema_refresh_delay, :schema_refresh_timeout,
220
+ :shuffle_replicas
195
221
  ].include?(key)
196
222
  end
197
223
 
198
- futures = options.fetch(:futures_factory, Future)
199
-
200
224
  has_username = options.has_key?(:username)
201
225
  has_password = options.has_key?(:password)
202
226
  if has_username || has_password
@@ -361,9 +385,23 @@ module Cassandra
361
385
  end
362
386
  end
363
387
 
388
+ if options.has_key?(:schema_refresh_delay)
389
+ timeout = options[:schema_refresh_delay]
390
+
391
+ Util.assert_instance_of(::Numeric, timeout) { ":schema_refresh_delay must be a number of seconds, #{timeout} given" }
392
+ Util.assert(timeout > 0) { ":schema_refresh_delay must be greater than 0, #{timeout} given" }
393
+ end
394
+
395
+ if options.has_key?(:schema_refresh_timeout)
396
+ timeout = options[:schema_refresh_timeout]
397
+
398
+ Util.assert_instance_of(::Numeric, timeout) { ":schema_refresh_timeout must be a number of seconds, #{timeout} given" }
399
+ Util.assert(timeout > 0) { ":schema_refresh_timeout must be greater than 0, #{timeout} given" }
400
+ end
401
+
364
402
  if options.has_key?(:load_balancing_policy)
365
403
  load_balancing_policy = options[:load_balancing_policy]
366
- methods = [:host_up, :host_down, :host_found, :host_lost, :setup, :distance, :plan]
404
+ methods = [:host_up, :host_down, :host_found, :host_lost, :setup, :teardown, :distance, :plan]
367
405
 
368
406
  Util.assert_responds_to_all(methods, load_balancing_policy) { ":load_balancing_policy #{load_balancing_policy.inspect} must respond to #{methods.inspect}, but doesn't" }
369
407
  end
@@ -382,9 +420,7 @@ module Cassandra
382
420
  end
383
421
 
384
422
  if options.has_key?(:listeners)
385
- listeners = options[:listeners]
386
-
387
- Util.assert_instance_of(::Enumerable, listeners) { ":listeners must be an Enumerable, #{listeners.inspect} given" }
423
+ options[:listeners] = Array(options[:listeners])
388
424
  end
389
425
 
390
426
  if options.has_key?(:consistency)
@@ -397,6 +433,10 @@ module Cassandra
397
433
  options[:trace] = !!options[:trace]
398
434
  end
399
435
 
436
+ if options.has_key?(:shuffle_replicas)
437
+ options[:shuffle_replicas] = !!options[:shuffle_replicas]
438
+ end
439
+
400
440
  if options.has_key?(:page_size)
401
441
  page_size = options[:page_size]
402
442
 
@@ -432,6 +472,10 @@ module Cassandra
432
472
  Util.assert_responds_to(:resolve, address_resolver) { ":address_resolution_policy must respond to :resolve, #{address_resolver.inspect} but doesn't" }
433
473
  end
434
474
 
475
+ if options.has_key?(:synchronize_schema)
476
+ options[:synchronize_schema] = !!options[:synchronize_schema]
477
+ end
478
+
435
479
  hosts = []
436
480
 
437
481
  Array(options.fetch(:hosts, '127.0.0.1')).each do |host|
@@ -450,20 +494,14 @@ module Cassandra
450
494
  if hosts.empty?
451
495
  raise ::ArgumentError, ":hosts #{options[:hosts].inspect} could not be resolved to any ip address"
452
496
  end
497
+
498
+ hosts.shuffle!
453
499
  rescue => e
500
+ futures = options.fetch(:futures_factory) { Driver.new.futures_factory }
454
501
  futures.error(e)
455
502
  else
456
- promise = futures.promise
457
-
458
- Driver.new(options).connect(hosts).on_complete do |f|
459
- if f.resolved?
460
- promise.fulfill(f.value)
461
- else
462
- f.on_failure {|e| promise.break(e)}
463
- end
464
- end
465
-
466
- promise.future
503
+ driver = Driver.new(options)
504
+ driver.connect(hosts)
467
505
  end
468
506
  end
469
507
 
@@ -475,6 +513,7 @@ require 'cassandra/protocol'
475
513
  require 'cassandra/auth'
476
514
  require 'cassandra/null_logger'
477
515
 
516
+ require 'cassandra/executors'
478
517
  require 'cassandra/future'
479
518
  require 'cassandra/cluster'
480
519
  require 'cassandra/driver'
@@ -18,9 +18,9 @@
18
18
 
19
19
  module Cassandra
20
20
  module Auth
21
- # An auth provider is a factory for {Cassandra::Auth::Authenticator} instances
22
- # (or objects matching that interface). Its {#create_authenticator} will be
23
- # called once for each connection that requires authentication.
21
+ # An auth provider is a factory for {Cassandra::Auth::Authenticator authenticator} instances (or objects matching that interface). Its
22
+ # {#create_authenticator} will be called once for each connection that
23
+ # requires authentication.
24
24
  #
25
25
  # If the authentication requires keeping state, keep that in the
26
26
  # authenticator instances, not in the auth provider.
@@ -17,8 +17,7 @@
17
17
  #++
18
18
 
19
19
  module Cassandra
20
- # Cluster represents a cassandra cluster. It serves as a {Cassandra::Session}
21
- # factory and a collection of metadata.
20
+ # Cluster represents a cassandra cluster. It serves as a {Cassandra::Session session factory} factory and a collection of metadata.
22
21
  #
23
22
  # @see Cassandra::Cluster#connect Creating a new session
24
23
  # @see Cassandra::Cluster#each_host Getting all peers in the cluster
@@ -26,46 +25,11 @@ module Cassandra
26
25
  class Cluster
27
26
  extend Forwardable
28
27
 
29
- # @!method host(address)
30
- # Find a host by its address
31
- # @param address [IPAddr, String] ip address
32
- # @return [Cassandra::Host, nil] host or nil
33
- #
34
- # @!method has_host?(address)
35
- # Determine if a host by a given address exists
36
- # @param address [IPAddr, String] ip address
37
- # @return [Boolean] true or false
38
- def_delegators :@registry, :host, :has_host?
39
-
40
- # @!method keyspace(name)
41
- # Find a keyspace by name
42
- # @param name [String] keyspace name
43
- # @return [Cassandra::Keyspace, nil] keyspace or nil
44
- #
45
- # @!method has_keyspace?(name)
46
- # Determine if a keyspace by a given name exists
47
- # @param name [String] keyspace name
48
- # @return [Boolean] true or false
49
- def_delegators :@schema, :keyspace, :has_keyspace?
50
-
51
- # @!method name
52
- # Return cluster's name
53
- # @return [String] cluster's name
54
- #
55
- # @!method find_replicas(keyspace, statement)
56
- # Return replicas for a given statement and keyspace
57
- # @note an empty list is returned when statement/keyspace information is
58
- # not enough to determine replica list.
59
- # @param keyspace [String] keyspace name
60
- # @param statement [Cassandra::Statement] statement for which to find
61
- # replicas
62
- # @return [Array<Cassandra::Host>] a list of replicas
63
- def_delegators :@metadata, :name, :find_replicas
64
-
65
28
  # @private
66
- def initialize(logger, io_reactor, control_connection, cluster_registry, cluster_schema, cluster_metadata, execution_options, connection_options, load_balancing_policy, reconnection_policy, retry_policy, address_resolution_policy, connector, futures_factory)
29
+ def initialize(logger, io_reactor, executor, control_connection, cluster_registry, cluster_schema, cluster_metadata, execution_options, connection_options, load_balancing_policy, reconnection_policy, retry_policy, address_resolution_policy, connector, futures_factory)
67
30
  @logger = logger
68
31
  @io_reactor = io_reactor
32
+ @executor = executor
69
33
  @control_connection = control_connection
70
34
  @registry = cluster_registry
71
35
  @schema = cluster_schema
@@ -78,8 +42,26 @@ module Cassandra
78
42
  @address_resolver = address_resolution_policy
79
43
  @connector = connector
80
44
  @futures = futures_factory
45
+
46
+ @control_connection.on_close do |cause|
47
+ @load_balancing_policy.teardown(self) rescue nil
48
+ end
81
49
  end
82
50
 
51
+ # @!method name
52
+ # Return cluster's name
53
+ # @return [String] cluster's name
54
+ #
55
+ # @!method find_replicas(keyspace, statement)
56
+ # Return replicas for a given statement and keyspace
57
+ # @note an empty list is returned when statement/keyspace information is
58
+ # not enough to determine replica list.
59
+ # @param keyspace [String] keyspace name
60
+ # @param statement [Cassandra::Statement] statement for which to find
61
+ # replicas
62
+ # @return [Array<Cassandra::Host>] a list of replicas
63
+ def_delegators :@metadata, :name, :find_replicas
64
+
83
65
  # Register a cluster state listener. State listener will start receiving
84
66
  # notifications about topology and schema changes
85
67
  #
@@ -115,6 +97,17 @@ module Cassandra
115
97
  end
116
98
  alias :hosts :each_host
117
99
 
100
+ # @!method host(address)
101
+ # Find a host by its address
102
+ # @param address [IPAddr, String] ip address
103
+ # @return [Cassandra::Host, nil] host or nil
104
+ #
105
+ # @!method has_host?(address)
106
+ # Determine if a host by a given address exists
107
+ # @param address [IPAddr, String] ip address
108
+ # @return [Boolean] true or false
109
+ def_delegators :@registry, :host, :has_host?
110
+
118
111
  # Yield or enumerate each keyspace defined in this cluster
119
112
  # @overload each_keyspace
120
113
  # @yieldparam keyspace [Cassandra::Keyspace] current keyspace
@@ -128,6 +121,35 @@ module Cassandra
128
121
  end
129
122
  alias :keyspaces :each_keyspace
130
123
 
124
+ # @!method keyspace(name)
125
+ # Find a keyspace by name
126
+ # @param name [String] keyspace name
127
+ # @return [Cassandra::Keyspace, nil] keyspace or nil
128
+ #
129
+ # @!method has_keyspace?(name)
130
+ # Determine if a keyspace by a given name exists
131
+ # @param name [String] keyspace name
132
+ # @return [Boolean] true or false
133
+ def_delegators :@schema, :keyspace, :has_keyspace?
134
+
135
+ # @!method refresh_schema_async
136
+ # Trigger an asynchronous schema metadata refresh
137
+ # @return [Cassandra::Future<nil>] a future that will be fulfilled when
138
+ # schema metadata has been refreshed
139
+ def_delegator :@control_connection, :refresh_schema_async_maybe_retry, \
140
+ :refresh_schema_async
141
+
142
+ # Synchronously refresh schema metadata
143
+ #
144
+ # @return [nil] nothing
145
+ # @raise [Cassandra::Errors::ClientError] when cluster is disconnected
146
+ # @raise [Cassandra::Error] other unexpected errors
147
+ #
148
+ # @see Cassandra::Cluster#refresh_schema_async
149
+ def refresh_schema
150
+ refresh_schema_async.get
151
+ end
152
+
131
153
  # Asynchronously create a new session, optionally scoped to a keyspace
132
154
  #
133
155
  # @param keyspace [String] optional keyspace to scope session to
@@ -191,11 +213,12 @@ module Cassandra
191
213
 
192
214
  @control_connection.close_async.on_complete do |f|
193
215
  if f.resolved?
194
- @load_balancing_policy.teardown(self) rescue nil
195
216
  promise.fulfill(self)
196
217
  else
197
218
  f.on_failure {|e| promise.break(e)}
198
219
  end
220
+
221
+ @executor.shutdown
199
222
  end
200
223
 
201
224
  promise.future