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 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