synchronised_migration 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 00db2582bb879e1481b044bbc394f3da0b84cfcc
4
- data.tar.gz: 3afb675d990294a656eec86f7bd539c7c5d82625
2
+ SHA256:
3
+ metadata.gz: 9c1431ba1cc8bb0ad840ba1020723cbefe53e2b88f3e40e80e24a203b7ab8163
4
+ data.tar.gz: 0faa2082f8cbceefcaa72b566d9ec16b02be2e19b27016ddf47e7a8f5d882659
5
5
  SHA512:
6
- metadata.gz: 0b50bb56d5ef420e3fd398f867659eed45ef72e0ff2058b15276c4da58f2068232222b860ea726126d628d5e71a0221065624e667476345841588b1ebad54e79
7
- data.tar.gz: 56d9d17730bf54bea7d9c4ba99584ce1dc0a582a046c494d03f44e283ba1ad435d00b3a9caacc53065af2ec9948ed252c4de3c80702d40c49f51b33b7160a215
6
+ metadata.gz: 842a04dca6b33503bf50d9563d688ea10c2ac624523b893a6f6314367dbff97c98cfecaf0dd9c82c32d0084323e1231aa81409a5616a6806b2b025b8fee9ffc2
7
+ data.tar.gz: d0be7428022db07f04c00d6017f29c2988035365c5ce76430cbae5177cd672d77aed79ff850e1a5a93987f25042a141cee384df6fe9ebdfabe7f117c0691fa1c
data/.gitignore CHANGED
@@ -2,3 +2,4 @@
2
2
  /vendor
3
3
  /coverage
4
4
  /*.gem
5
+ Gemfile.lock
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.2.7
1
+ 2.6.3
data/.travis.yml CHANGED
@@ -1,3 +1,10 @@
1
- ---
2
1
  language: ruby
3
- script: bundle && bundle exec rspec
2
+ rvm:
3
+ - 2.4
4
+ - 2.5
5
+ - 2.6
6
+ script: bundle exec rspec
7
+ sudo: false
8
+ cache: bundler
9
+ before_install:
10
+ - gem install bundler
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Synchronised Migration
2
2
 
3
+ ## 2.1.0
4
+
5
+ * [TT-5827] Add "success key" when REDLOCK_VERSION_SUFFIX is set, preventing repeat runs
6
+ * [TT-5830] Add rake and Rakefile for 'rake release'
7
+
3
8
  ## 2.0.0
4
9
 
5
10
  * [DO-168] Removed requirement for defining RedisConfig, now set on
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
@@ -15,11 +15,16 @@ class SynchronisedMigration::Main
15
15
  end
16
16
 
17
17
  def call
18
- lock_and_execute
18
+ done_or_execute
19
19
  end
20
20
 
21
21
  private
22
22
 
23
+ def done_or_execute
24
+ return Result.ok if migration_already_completed?
25
+ lock_and_execute
26
+ end
27
+
23
28
  def lock_and_execute
24
29
  redlock.lock! lock_key, timeout do
25
30
  execute
@@ -27,12 +32,25 @@ class SynchronisedMigration::Main
27
32
  end
28
33
 
29
34
  def execute
30
- return Result.new 'Halting the script because the previous migration failed.' if previous_failed?
35
+ return Result.fail 'Halting the script because the previous migration failed.' if previous_failed?
31
36
  mark_failed
32
37
  migrate
33
- return Result.new 'Migration failed.' if migration_failed?
38
+ return Result.fail 'Migration failed.' if migration_failed?
39
+ mark_successful
34
40
  remove_fail_marker
35
- Result.new
41
+ return Result.ok
42
+ end
43
+
44
+ def migration_already_completed?
45
+ return false if !success_key
46
+ value = redis.get(success_key)
47
+ not value.nil? and not value.empty?
48
+ end
49
+
50
+ def mark_successful
51
+ if success_key
52
+ redis.set success_key, timestamp, ttl: 3600*24*30
53
+ end
36
54
  end
37
55
 
38
56
  def previous_failed?
@@ -41,7 +59,7 @@ class SynchronisedMigration::Main
41
59
  end
42
60
 
43
61
  def mark_failed
44
- redis.set fail_key, 1
62
+ redis.set fail_key, timestamp, ttl: 3600
45
63
  end
46
64
 
47
65
  def remove_fail_marker
@@ -89,12 +107,16 @@ class SynchronisedMigration::Main
89
107
  )
90
108
  end
91
109
 
110
+ def timestamp
111
+ Time.now.to_i
112
+ end
113
+
92
114
  def timeout
93
115
  ENV.fetch('REDLOCK_TIMEOUT_MS', 3_600_000).to_i
94
116
  end
95
117
 
96
118
  def retry_delay
97
- ENV.fetch('REDLOCK_RETRY_DELAY_MS', 200).to_i
119
+ ENV.fetch('REDLOCK_RETRY_DELAY_MS', 3000).to_i
98
120
  end
99
121
 
100
122
  def retry_count
@@ -106,6 +128,16 @@ class SynchronisedMigration::Main
106
128
  end
107
129
 
108
130
  def fail_key
109
- ENV.fetch 'REDLOCK_FAIL_KEY', 'migration-failed'
131
+ ENV.fetch 'REDLOCK_FAIL_KEY', 'migration-failed' + version_suffix
132
+ end
133
+
134
+ def success_key
135
+ return false if version_suffix.empty?
136
+ 'migration-success' + version_suffix
137
+ end
138
+
139
+ def version_suffix
140
+ suffix = ENV.fetch 'REDLOCK_VERSION_SUFFIX', false
141
+ suffix ? '-' + suffix : ''
110
142
  end
111
143
  end
@@ -10,4 +10,12 @@ class SynchronisedMigration::Result
10
10
  def success?
11
11
  error.nil?
12
12
  end
13
+
14
+ def self.ok
15
+ self.new
16
+ end
17
+
18
+ def self.fail(error)
19
+ self.new error
20
+ end
13
21
  end
@@ -1,3 +1,3 @@
1
1
  module SynchronisedMigration
2
- VERSION = '2.0.0'
2
+ VERSION = '2.1.0'
3
3
  end
@@ -9,19 +9,26 @@ describe SynchronisedMigration::Main do
9
9
  let(:redis) { double }
10
10
  let(:redlock) { double }
11
11
  let(:fail_marker_value) { nil }
12
+ let(:success_marker_value) { nil }
13
+ let(:set_version_suffix) { ENV['REDLOCK_VERSION_SUFFIX'] = 'bork' }
14
+ let(:time_value) { double(to_i: 123456789) }
12
15
 
13
16
  before do
17
+ set_version_suffix
18
+
14
19
  subject.instance.instance_variable_set :@redis, nil
15
20
  subject.instance.instance_variable_set :@redlock, nil
16
21
 
17
22
  allow(Redis).to receive(:new).and_return(redis)
18
- allow(redis).to receive(:get).and_return(fail_marker_value)
23
+ allow(redis).to receive(:get).and_return(success_marker_value, fail_marker_value)
19
24
  allow(redis).to receive(:set)
20
25
  allow(redis).to receive(:del)
21
26
 
22
27
  allow(Redlock::Client).to receive(:new).and_return(redlock)
23
28
  allow(redlock).to receive(:lock!) { |lock_key, timeout, &block| block.call }
24
29
 
30
+ allow(Time).to receive(:now).and_return(time_value)
31
+
25
32
  allow(Kernel).to receive(:system).and_wrap_original { |method, *args|
26
33
  next if args == [ 'bin/launch/migrate' ]
27
34
  method.call *args
@@ -40,11 +47,20 @@ describe SynchronisedMigration::Main do
40
47
  it 'executes the migration successfully' do
41
48
  expect(result).to be_success
42
49
  expect(redlock).to have_received(:lock!)
43
- expect(redis).to have_received(:get).with('migration-failed')
44
- expect(redis).to have_received(:set).with('migration-failed', 1)
50
+ expect(redis).to have_received(:get).with('migration-failed-bork')
51
+ expect(redis).to have_received(:set).with('migration-failed-bork', 123456789, ttl: 3600)
52
+ expect(redis).to have_received(:set).with('migration-success-bork', 123456789, ttl: 3600*24*30)
45
53
  expect(Kernel).to have_received(:system)
46
54
  expect(Bundler).not_to have_received(:with_original_env)
47
- expect(redis).to have_received(:del).with('migration-failed')
55
+ expect(redis).to have_received(:del).with('migration-failed-bork')
56
+ end
57
+
58
+ context 'and migration completed previously' do
59
+ let(:success_marker_value) { '1' }
60
+ it 'contines without executing' do
61
+ expect(result).to be_success
62
+ expect(redlock).not_to have_received(:lock!)
63
+ end
48
64
  end
49
65
  end
50
66
 
@@ -77,9 +93,37 @@ describe SynchronisedMigration::Main do
77
93
 
78
94
  it 'marks the failure in Redis' do
79
95
  expect(result).not_to be_success
80
- expect(redis).to have_received(:set).with('migration-failed', 1)
96
+ expect(redis).to have_received(:set).with('migration-failed-bork', 123456789, ttl: 3600)
81
97
  expect(redis).not_to have_received(:del)
82
98
  end
83
99
  end
100
+
101
+ context 'without version suffix' do
102
+ let(:set_version_suffix) { ENV.delete 'REDLOCK_VERSION_SUFFIX' }
103
+
104
+ context 'in the happy path' do
105
+ it 'executes the migration successfully' do
106
+ expect(result).to be_success
107
+ expect(redlock).to have_received(:lock!)
108
+ expect(redis).to have_received(:get).with('migration-failed')
109
+ expect(redis).to have_received(:set).with('migration-failed', 123456789, ttl: 3600)
110
+ expect(Kernel).to have_received(:system)
111
+ expect(Bundler).not_to have_received(:with_original_env)
112
+ expect(redis).to have_received(:del).with('migration-failed')
113
+ end
114
+ end
115
+
116
+ context 'when the task crashed' do
117
+ before do
118
+ allow_any_instance_of(Process::Status).to receive(:success?).and_return(false)
119
+ end
120
+
121
+ it 'marks the failure in Redis' do
122
+ expect(result).not_to be_success
123
+ expect(redis).to have_received(:set).with('migration-failed', 123456789, ttl: 3600)
124
+ expect(redis).not_to have_received(:del)
125
+ end
126
+ end
127
+ end
84
128
  end
85
129
  end
@@ -16,8 +16,9 @@ Gem::Specification.new do |spec|
16
16
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
17
  spec.require_paths = ['lib']
18
18
 
19
- spec.add_dependency 'redlock', '~> 0.2'
20
- spec.add_development_dependency 'simplecov-rcov', '~> 0.2'
21
- spec.add_development_dependency 'rspec', '~> 3.6'
22
- spec.add_development_dependency 'pry-byebug', '~> 3.5'
19
+ spec.add_dependency 'redlock', '>= 0.2'
20
+ spec.add_development_dependency 'rake'
21
+ spec.add_development_dependency 'simplecov-rcov', '>= 0.2'
22
+ spec.add_development_dependency 'rspec', '>= 3.6'
23
+ spec.add_development_dependency 'pry-byebug', '>= 3.5'
23
24
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: synchronised_migration
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alvin Yim
@@ -9,62 +9,76 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2018-04-17 00:00:00.000000000 Z
12
+ date: 2019-08-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: redlock
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - "~>"
18
+ - - ">="
19
19
  - !ruby/object:Gem::Version
20
20
  version: '0.2'
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
- - - "~>"
25
+ - - ">="
26
26
  - !ruby/object:Gem::Version
27
27
  version: '0.2'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
28
42
  - !ruby/object:Gem::Dependency
29
43
  name: simplecov-rcov
30
44
  requirement: !ruby/object:Gem::Requirement
31
45
  requirements:
32
- - - "~>"
46
+ - - ">="
33
47
  - !ruby/object:Gem::Version
34
48
  version: '0.2'
35
49
  type: :development
36
50
  prerelease: false
37
51
  version_requirements: !ruby/object:Gem::Requirement
38
52
  requirements:
39
- - - "~>"
53
+ - - ">="
40
54
  - !ruby/object:Gem::Version
41
55
  version: '0.2'
42
56
  - !ruby/object:Gem::Dependency
43
57
  name: rspec
44
58
  requirement: !ruby/object:Gem::Requirement
45
59
  requirements:
46
- - - "~>"
60
+ - - ">="
47
61
  - !ruby/object:Gem::Version
48
62
  version: '3.6'
49
63
  type: :development
50
64
  prerelease: false
51
65
  version_requirements: !ruby/object:Gem::Requirement
52
66
  requirements:
53
- - - "~>"
67
+ - - ">="
54
68
  - !ruby/object:Gem::Version
55
69
  version: '3.6'
56
70
  - !ruby/object:Gem::Dependency
57
71
  name: pry-byebug
58
72
  requirement: !ruby/object:Gem::Requirement
59
73
  requirements:
60
- - - "~>"
74
+ - - ">="
61
75
  - !ruby/object:Gem::Version
62
76
  version: '3.5'
63
77
  type: :development
64
78
  prerelease: false
65
79
  version_requirements: !ruby/object:Gem::Requirement
66
80
  requirements:
67
- - - "~>"
81
+ - - ">="
68
82
  - !ruby/object:Gem::Version
69
83
  version: '3.5'
70
84
  description: Use Redis to record the data migration status
@@ -78,9 +92,9 @@ files:
78
92
  - ".travis.yml"
79
93
  - CHANGELOG.md
80
94
  - Gemfile
81
- - Gemfile.lock
82
95
  - LICENSE
83
96
  - README.md
97
+ - Rakefile
84
98
  - lib/synchronised_migration.rb
85
99
  - lib/synchronised_migration/main.rb
86
100
  - lib/synchronised_migration/railtie.rb
@@ -108,8 +122,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
108
122
  - !ruby/object:Gem::Version
109
123
  version: '0'
110
124
  requirements: []
111
- rubyforge_project:
112
- rubygems_version: 2.4.5.2
125
+ rubygems_version: 3.0.3
113
126
  signing_key:
114
127
  specification_version: 4
115
128
  summary: For deploying to multiple instances simultaneously
data/Gemfile.lock DELETED
@@ -1,58 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- synchronised_migration (2.0.0)
5
- redlock (~> 0.2)
6
-
7
- GEM
8
- remote: https://rubygems.org/
9
- specs:
10
- byebug (9.1.0)
11
- coderay (1.1.2)
12
- diff-lcs (1.3)
13
- docile (1.1.5)
14
- json (2.1.0)
15
- method_source (0.8.2)
16
- pry (0.10.4)
17
- coderay (~> 1.1.0)
18
- method_source (~> 0.8.1)
19
- slop (~> 3.4)
20
- pry-byebug (3.5.0)
21
- byebug (~> 9.1)
22
- pry (~> 0.10)
23
- redis (4.0.1)
24
- redlock (0.2.2)
25
- redis (>= 3.0.0, < 5.0)
26
- rspec (3.6.0)
27
- rspec-core (~> 3.6.0)
28
- rspec-expectations (~> 3.6.0)
29
- rspec-mocks (~> 3.6.0)
30
- rspec-core (3.6.0)
31
- rspec-support (~> 3.6.0)
32
- rspec-expectations (3.6.0)
33
- diff-lcs (>= 1.2.0, < 2.0)
34
- rspec-support (~> 3.6.0)
35
- rspec-mocks (3.6.0)
36
- diff-lcs (>= 1.2.0, < 2.0)
37
- rspec-support (~> 3.6.0)
38
- rspec-support (3.6.0)
39
- simplecov (0.15.0)
40
- docile (~> 1.1.0)
41
- json (>= 1.8, < 3)
42
- simplecov-html (~> 0.10.0)
43
- simplecov-html (0.10.2)
44
- simplecov-rcov (0.2.3)
45
- simplecov (>= 0.4.1)
46
- slop (3.6.0)
47
-
48
- PLATFORMS
49
- ruby
50
-
51
- DEPENDENCIES
52
- pry-byebug (~> 3.5)
53
- rspec (~> 3.6)
54
- simplecov-rcov (~> 0.2)
55
- synchronised_migration!
56
-
57
- BUNDLED WITH
58
- 1.16.1