synchronised_migration 2.0.0 → 2.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.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/.ruby-version +1 -1
- data/.travis.yml +9 -2
- data/CHANGELOG.md +5 -0
- data/Rakefile +2 -0
- data/lib/synchronised_migration/main.rb +39 -7
- data/lib/synchronised_migration/result.rb +8 -0
- data/lib/synchronised_migration/version.rb +1 -1
- data/spec/synchronised_migration/main_spec.rb +49 -5
- data/synchronised_migration.gemspec +5 -4
- metadata +26 -13
- data/Gemfile.lock +0 -58
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9c1431ba1cc8bb0ad840ba1020723cbefe53e2b88f3e40e80e24a203b7ab8163
|
4
|
+
data.tar.gz: 0faa2082f8cbceefcaa72b566d9ec16b02be2e19b27016ddf47e7a8f5d882659
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 842a04dca6b33503bf50d9563d688ea10c2ac624523b893a6f6314367dbff97c98cfecaf0dd9c82c32d0084323e1231aa81409a5616a6806b2b025b8fee9ffc2
|
7
|
+
data.tar.gz: d0be7428022db07f04c00d6017f29c2988035365c5ce76430cbae5177cd672d77aed79ff850e1a5a93987f25042a141cee384df6fe9ebdfabe7f117c0691fa1c
|
data/.gitignore
CHANGED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.6.3
|
data/.travis.yml
CHANGED
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
@@ -15,11 +15,16 @@ class SynchronisedMigration::Main
|
|
15
15
|
end
|
16
16
|
|
17
17
|
def call
|
18
|
-
|
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.
|
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.
|
38
|
+
return Result.fail 'Migration failed.' if migration_failed?
|
39
|
+
mark_successful
|
34
40
|
remove_fail_marker
|
35
|
-
Result.
|
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,
|
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',
|
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
|
@@ -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',
|
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',
|
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', '
|
20
|
-
spec.add_development_dependency '
|
21
|
-
spec.add_development_dependency '
|
22
|
-
spec.add_development_dependency '
|
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.
|
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:
|
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
|
-
|
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
|