cassandra-schema 0.3.0 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 646b6d54404b35f5f4925709947d873dc7bf2880
4
- data.tar.gz: 5550c316d8f6fa5460f7db981654344e347a5252
3
+ metadata.gz: c1df802181e12870f46be28f9ffb5a0520d6ba0a
4
+ data.tar.gz: 2b0492a941204bf66ed2a78a9b4a803bf5df34e2
5
5
  SHA512:
6
- metadata.gz: c4a88f2462cafff564678761264402e76da9574f9d1b6df02ce008363a51cc96b7af3d06ceb0354e7de61b2e4d90e94d51354b75b9f9a41325463ade1bd5298f
7
- data.tar.gz: c64a715befaed5b60ff833ad8a61a4ef07ac67e50a842d94fc3595c9f9e5d3ef7c14966f25373b990bc9671f6163668f6ef2e5d7afeae973179520e9f5bbe16f
6
+ metadata.gz: 6f45ca854b3faaa1efa1ead0692e58bc809b06e912d6b133e385b53efe3824d70075cbe4b388864910b100d9bdbc94f85642d73eccef791eaab39abf74fe3534
7
+ data.tar.gz: 3ad6a515d4290b1c6766d39e7b65ddc46740d65cb711d27e2375c65e5a86af00b584e689d5e196385c06c1c03919f1c34abf6a59bfd81fea681e13941a0ca0a7
data/README.md CHANGED
@@ -4,6 +4,11 @@ Simple reversible schema migrations for cassandra.
4
4
 
5
5
  ## Changelog
6
6
 
7
+ ### Version `0.4.0`
8
+
9
+ - Add `query_delay` option to configure sleep time between schema changes. Default `0`.
10
+ - Add `lock_retry` option to retry migration if schema is locked. Default `[]`
11
+
7
12
  ### Version `0.3.0`
8
13
 
9
14
  - Add `query_timeout` option for running migration commands. Default 30 seconds.
@@ -91,11 +96,13 @@ CassandraSchema tracks which migrations you have already run.
91
96
 
92
97
  ### Options
93
98
 
94
- name | default | description
95
- ---- | ------- | -----------
96
- lock | true | whether the Migrator must lock the schema before running migrations
97
- lock_timeout | 30 | number of seconds for auto-unlocking schema
98
- query_timeout | 30 | number of seconds after which to time out the command if it hasn’t completed
99
+ name | default | description | example
100
+ ---- | ------- | ----------- | -------
101
+ lock | true | whether the Migrator must lock the schema before running migrations |
102
+ lock_timeout | 30 | number of seconds for auto-unlocking schema |
103
+ lock_retry | [] | array of retries. The size of the array is the max number of retries. Each item of the array is the number of seconds to wait until the next retry. | [1, 1, 2, 3, 5, 8]
104
+ query_timeout | 30 | number of seconds after which to time out the command if it hasn’t completed |
105
+ query_delay | 0 | number of millisenconds to wait after each schema change |
99
106
 
100
107
  ## Installation
101
108
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "cassandra-schema"
5
- s.version = "0.3.0"
5
+ s.version = "0.4.0"
6
6
  s.summary = "Cassandra schema migrations"
7
7
  s.license = "MIT"
8
8
  s.description = "Simple reversible schema migrations for Cassandra."
@@ -7,7 +7,9 @@ module CassandraSchema
7
7
  DEFAULT_OPTIONS = {
8
8
  lock: true,
9
9
  lock_timeout: 30,
10
+ lock_retry: [],
10
11
  query_timeout: 30,
12
+ query_delay: 0,
11
13
  }
12
14
 
13
15
  def initialize(connection:, migrations:, logger: Logger.new(STDOUT), options: {})
@@ -20,7 +22,17 @@ module CassandraSchema
20
22
  end
21
23
 
22
24
  def migrate(target = nil)
23
- if @options.fetch(:lock) && !lock_schema
25
+ lock_retry = @options.fetch(:lock_retry).dup
26
+
27
+ begin
28
+ raise if @options.fetch(:lock) && !lock_schema
29
+ rescue
30
+ if wait = lock_retry.shift
31
+ @logger.info "Schema is locked; retrying in #{wait} seconds"
32
+ sleep wait
33
+ retry
34
+ end
35
+
24
36
  @logger.info "Can't run migrations. Schema is locked."
25
37
  return
26
38
  end
@@ -195,8 +207,18 @@ module CassandraSchema
195
207
  end
196
208
 
197
209
  def execute_command(command, options)
210
+ query_delay = @options.fetch(:query_delay)
211
+
198
212
  begin
199
213
  @connection.execute command, options
214
+
215
+ # There is a Cassandra bug, where schema changes executed in quick succession
216
+ # can result in internal corruption:
217
+ #
218
+ # https://stackoverflow.com/questions/29030661/creating-new-table-with-cqlsh-on-existing-keyspace-column-family-id-mismatch#answer
219
+ # https://issues.apache.org/jira/browse/CASSANDRA-5025
220
+ delay(query_delay / 1000.0) if query_delay > 0
221
+
200
222
  true
201
223
  rescue => ex
202
224
  @logger.error ex.message
@@ -204,5 +226,8 @@ module CassandraSchema
204
226
  end
205
227
  end
206
228
 
229
+ private def delay(delay_time)
230
+ sleep(delay_time)
231
+ end
207
232
  end
208
233
  end
@@ -1,3 +1,3 @@
1
1
  module CassandraSchema
2
- VERSION = "0.2.0"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -100,7 +100,7 @@ describe "CassandraSchema::Migrator" do
100
100
  end
101
101
 
102
102
  it "initializes schema_information table if not exists" do
103
- migrator = CassandraSchema::Migrator.new(
103
+ CassandraSchema::Migrator.new(
104
104
  connection: CONN,
105
105
  migrations: {},
106
106
  logger: @fake_logger,
@@ -187,6 +187,43 @@ describe "CassandraSchema::Migrator" do
187
187
  assert_equal "Nothing to migrate.", logger_b.stdout.pop
188
188
  end
189
189
 
190
+ it "retries if schema is locked" do
191
+ migrator = CassandraSchema::Migrator.new(
192
+ connection: CONN,
193
+ migrations: CassandraSchema.migrations,
194
+ logger: @fake_logger,
195
+ options: { lock_retry: [1, 1, 2, 3] },
196
+ )
197
+
198
+ migrator.expects(:lock_schema).times(4).returns(false, false, false, true)
199
+
200
+ migrator.migrate
201
+
202
+ assert_equal "Schema is locked; retrying in 1 seconds", @fake_logger.stdout.shift
203
+ assert_equal "Schema is locked; retrying in 1 seconds", @fake_logger.stdout.shift
204
+ assert_equal "Schema is locked; retrying in 2 seconds", @fake_logger.stdout.shift
205
+ assert_equal "Running migrations...", @fake_logger.stdout.shift
206
+
207
+ assert_equal 2, migrator.current_version
208
+ end
209
+
210
+ it "fails if schema is locked after retring" do
211
+ migrator = CassandraSchema::Migrator.new(
212
+ connection: CONN,
213
+ migrations: CassandraSchema.migrations,
214
+ logger: @fake_logger,
215
+ options: { lock_retry: [1, 1] },
216
+ )
217
+
218
+ migrator.expects(:lock_schema).times(3).returns(false, false, false)
219
+
220
+ migrator.migrate
221
+
222
+ assert_equal "Schema is locked; retrying in 1 seconds", @fake_logger.stdout.shift
223
+ assert_equal "Schema is locked; retrying in 1 seconds", @fake_logger.stdout.shift
224
+ assert_equal "Can't run migrations. Schema is locked.", @fake_logger.stdout.shift
225
+ end
226
+
190
227
  it "runs commands with custom timeout" do
191
228
  migrator = CassandraSchema::Migrator.new(
192
229
  connection: CONN,
@@ -205,6 +242,26 @@ describe "CassandraSchema::Migrator" do
205
242
 
206
243
  migrator.migrate
207
244
  end
245
+
246
+ it "runs commands with custom delay" do
247
+ migrator = CassandraSchema::Migrator.new(
248
+ connection: CONN,
249
+ migrations: CassandraSchema.migrations,
250
+ logger: @fake_logger,
251
+ options: {
252
+ query_delay: 500,
253
+ },
254
+ )
255
+
256
+ migrator.expects(:delay).times(4).with(0.5)
257
+
258
+ migrator.expects(:lock_schema).returns(true)
259
+ migrator.expects(:get_current_version).returns(0)
260
+ migrator.expects(:update_version).times(2)
261
+ migrator.expects(:renew_lock).times(2)
262
+
263
+ migrator.migrate
264
+ end
208
265
  end
209
266
 
210
267
  describe "migrating down" do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cassandra-schema
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lautaro Orazi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-09 00:00:00.000000000 Z
11
+ date: 2018-05-30 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Simple reversible schema migrations for Cassandra.
14
14
  email: