cassandra-driver 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -118,6 +118,13 @@ module Cassandra
118
118
  Keyspace.new(@name, @durable_writes, @replication, tables)
119
119
  end
120
120
 
121
+ # @private
122
+ def delete_table(table_name)
123
+ tables = @tables.dup
124
+ tables.delete(table_name)
125
+ Keyspace.new(@name, @durable_writes, @replication, tables)
126
+ end
127
+
121
128
  # @private
122
129
  def create_partition_key(table, values)
123
130
  table = @tables[table]
@@ -28,11 +28,21 @@ module Cassandra
28
28
  class Policy
29
29
  # Allows policy to initialize with the cluster instance. This method is
30
30
  # called once before connecting to the cluster.
31
+ #
31
32
  # @param cluster [Cassandra::Cluster] current cluster instance
32
33
  # @return [void]
33
34
  def setup(cluster)
34
35
  end
35
36
 
37
+ # Allows policy to release any external resources it might be holding.
38
+ # This method is called once the cluster has been terminated after calling
39
+ # {Cassandra::Cluster#close}
40
+ #
41
+ # @param cluster [Cassandra::Cluster] current cluster instance
42
+ # @return [void]
43
+ def teardown(cluster)
44
+ end
45
+
36
46
  # @see Cassandra::Listener#host_up
37
47
  def host_up(host)
38
48
  end
@@ -136,12 +136,12 @@ module Cassandra
136
136
  remote = @remote
137
137
  end
138
138
 
139
- position = @position
140
- total = local.size + remote.size
139
+ total = local.size + remote.size
141
140
 
142
141
  return EMPTY_PLAN if total == 0
143
142
 
144
- @position = (@position + 1) % total
143
+ position = @position % total
144
+ @position = position + 1
145
145
 
146
146
  Plan.new(local, remote, position)
147
147
  end
@@ -37,7 +37,8 @@ module Cassandra
37
37
  return if @remaining == 0
38
38
 
39
39
  @remaining -= 1
40
- index, @index = @index, (@index + 1) % @total
40
+ index = @index
41
+ @index = (index + 1) % @total
41
42
 
42
43
  @hosts[index]
43
44
  end
@@ -117,12 +118,13 @@ module Cassandra
117
118
  # @return [Cassandra::LoadBalancing::Plan] a rotated load balancing plan
118
119
  # @see Cassandra::LoadBalancing::Policy#plan
119
120
  def plan(keyspace, statement, options)
120
- hosts = @hosts
121
- position = @position
122
- total = hosts.size
121
+ hosts = @hosts
122
+ total = hosts.size
123
+
123
124
  return EMPTY_PLAN if total == 0
124
125
 
125
- @position = (position + 1) % total
126
+ position = @position % total
127
+ @position = position + 1
126
128
 
127
129
  Plan.new(hosts, position)
128
130
  end
@@ -88,13 +88,24 @@ module Cassandra
88
88
  # @see Cassandra::LoadBalancing::Policy#host_lost
89
89
  def_delegators :@policy, :distance, :host_found, :host_up, :host_down, :host_lost
90
90
 
91
- # @param wrapped_policy [Cassandra::LoadBalancing::Policy] actual policy to filter
92
- def initialize(wrapped_policy)
93
- methods = [:host_up, :host_down, :host_found, :host_lost, :distance, :plan]
91
+ # @param wrapped_policy [Cassandra::LoadBalancing::Policy] actual
92
+ # policy to filter
93
+ # @param shuffle [Boolean] (true) whether or not to shuffle the replicas
94
+ #
95
+ # @note If replicas are not shuffled (`shuffle = false`), then it is
96
+ # possibile to create hotspots in a write-heavy scenario, where most
97
+ # of the write requests will be handled by the same node(s). The
98
+ # default behavior of shuffling replicas helps mitigate this by
99
+ # universally distributing write load between replicas. However, it
100
+ # under-utilizes read caching and forces multiple replicas to cache
101
+ # the same read statements.
102
+ def initialize(wrapped_policy, shuffle = true)
103
+ methods = [:host_up, :host_down, :host_found, :host_lost, :setup, :teardown, :distance, :plan]
94
104
 
95
105
  Util.assert_responds_to_all(methods, wrapped_policy) { "supplied policy must respond to #{methods.inspect}, but doesn't" }
96
106
 
97
- @policy = wrapped_policy
107
+ @policy = wrapped_policy
108
+ @shuffle = !!shuffle
98
109
  end
99
110
 
100
111
  def setup(cluster)
@@ -103,13 +114,25 @@ module Cassandra
103
114
  nil
104
115
  end
105
116
 
117
+ def teardown(cluster)
118
+ @cluster = nil
119
+ @policy.teardown(cluster)
120
+ nil
121
+ end
122
+
106
123
  def plan(keyspace, statement, options)
107
124
  return @policy.plan(keyspace, statement, options) unless @cluster
108
125
 
109
126
  replicas = @cluster.find_replicas(keyspace, statement)
110
127
  return @policy.plan(keyspace, statement, options) if replicas.empty?
111
128
 
112
- Plan.new(replicas.shuffle, @policy, keyspace, statement, options)
129
+ if @shuffle
130
+ replicas = replicas.shuffle
131
+ else
132
+ replicas = replicas.dup
133
+ end
134
+
135
+ Plan.new(replicas, @policy, keyspace, statement, options)
113
136
  end
114
137
  end
115
138
  end
@@ -36,7 +36,7 @@ module Cassandra
36
36
  # @raise [ArgumentError] if arguments are of unexpected types
37
37
  def initialize(ips, wrapped_policy)
38
38
  Util.assert_instance_of(::Enumerable, ips) { "ips must be an Enumerable, #{ips.inspect} given" }
39
- methods = [:host_up, :host_down, :host_found, :host_lost, :distance, :plan]
39
+ methods = [:host_up, :host_down, :host_found, :host_lost, :setup, :teardown, :distance, :plan]
40
40
  Util.assert_responds_to_all(methods, wrapped_policy) { "supplied policy must respond to #{methods.inspect}, but doesn't" }
41
41
 
42
42
  @ips = ::Set.new
@@ -190,7 +190,10 @@ module Cassandra
190
190
  @terminate = nil
191
191
  end
192
192
 
193
- @connection.close(cause)
193
+ @scheduler.schedule_timer(0).on_value do
194
+ @connection.close(cause)
195
+ end
196
+
194
197
  @closed_promise.future
195
198
  end
196
199
 
@@ -51,6 +51,8 @@ module Cassandra
51
51
  # @param options [Hash] additional options, just like the ones for
52
52
  # {Cassandra::Session#execute}
53
53
  #
54
+ # @note `:paging_state` option will be ignored.
55
+ #
54
56
  # @return [Cassandra::Result, nil] returns `nil` if last page
55
57
  #
56
58
  # @see Cassandra::Session#execute
@@ -62,17 +64,38 @@ module Cassandra
62
64
  # @param options [Hash] additional options, just like the ones for
63
65
  # {Cassandra::Session#execute_async}
64
66
  #
67
+ # @note `:paging_state` option will be ignored.
68
+ #
65
69
  # @return [Cassandra::Future<Cassandra::Result, nil>] `nil` if last
66
70
  # page
67
71
  #
68
72
  # @see Cassandra::Session#execute
69
73
  def next_page_async(options = nil)
70
74
  end
75
+
76
+ # Exposes current paging state for stateless pagination.
77
+ #
78
+ # @return [String, nil] current paging state as a `String` or `nil`.
79
+ #
80
+ # @note Although this feature exists to allow web applications to store
81
+ # paging state in an [HTTP cookie](http://en.wikipedia.org/wiki/HTTP_cookie), **it is not safe to
82
+ # expose without encrypting or otherwise securing it**. Paging state
83
+ # contains information internal to the Apache Cassandra cluster, such as
84
+ # partition key and data. Additionally, if a paging state is sent with CQL
85
+ # statement, different from the original, the behavior of Cassandra is
86
+ # undefined and will likely cause a server process of the coordinator of
87
+ # such request to abort.
88
+ #
89
+ # @see https://github.com/apache/cassandra/blob/trunk/doc/native_protocol_v2.spec#L482-L487 Paging State description in Cassandra Native Protocol v2 specification
90
+ def paging_state
91
+ end
71
92
  end
72
93
 
73
94
  # @private
74
95
  module Results
75
96
  class Paged < Result
97
+ attr_reader :paging_state
98
+
76
99
  def initialize(rows, paging_state, trace_id, keyspace, statement, options, hosts, consistency, retries, client, futures_factory)
77
100
  @rows = rows
78
101
  @paging_state = paging_state
@@ -124,12 +147,12 @@ module Cassandra
124
147
  def next_page_async(options = nil)
125
148
  return @futures.value(nil) if @paging_state.nil?
126
149
 
127
- options = options ? @options.override(options) : @options
150
+ options = @options.override(options, paging_state: @paging_state)
128
151
 
129
152
  if @statement.is_a?(Statements::Simple)
130
- @client.query(@statement, options, @paging_state)
153
+ @client.query(@statement, options)
131
154
  else
132
- @client.execute(@statement, options, @paging_state)
155
+ @client.execute(@statement, options)
133
156
  end
134
157
  end
135
158
 
@@ -201,6 +224,10 @@ module Cassandra
201
224
  nil
202
225
  end
203
226
 
227
+ def paging_state
228
+ nil
229
+ end
230
+
204
231
  def inspect
205
232
  "#<Cassandra::Result:0x#{self.object_id.to_s(16)} @rows=[] @last_page=true>"
206
233
  end
@@ -53,6 +53,9 @@ module Cassandra
53
53
  # @option options [Symbol] :serial_consistency (nil) this option is only
54
54
  # relevant for conditional updates and specifies a serial consistency to
55
55
  # be used, one of {Cassandra::SERIAL_CONSISTENCIES}
56
+ # @option options [String] :paging_state (nil) this option is used for
57
+ # stateless paging, where result paging is resumed some time after the
58
+ # initial request.
56
59
  #
57
60
  # @see Cassandra.cluster Options that can be specified on the cluster-level
58
61
  # and their default values.
@@ -17,5 +17,5 @@
17
17
  #++
18
18
 
19
19
  module Cassandra
20
- VERSION = '1.0.0'.freeze
20
+ VERSION = '1.1.0'.freeze
21
21
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cassandra-driver
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Theo Hultberg
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-11-19 00:00:00.000000000 Z
12
+ date: 2014-12-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ione
@@ -103,6 +103,7 @@ files:
103
103
  - lib/cassandra/execution/info.rb
104
104
  - lib/cassandra/execution/options.rb
105
105
  - lib/cassandra/execution/trace.rb
106
+ - lib/cassandra/executors.rb
106
107
  - lib/cassandra/future.rb
107
108
  - lib/cassandra/host.rb
108
109
  - lib/cassandra/keyspace.rb