lhm-shopify 4.2.3 → 4.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 +4 -4
- data/.github/workflows/test.yml +6 -3
- data/Appraisals +4 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile.lock +26 -25
- data/dev.yml +2 -4
- data/gemfiles/activerecord_6.1.gemfile.lock +1 -1
- data/gemfiles/activerecord_7.0.gemfile.lock +1 -1
- data/gemfiles/activerecord_7.1.gemfile.lock +1 -1
- data/gemfiles/activerecord_head.gemfile +7 -0
- data/gemfiles/activerecord_head.gemfile.lock +88 -0
- data/lib/lhm/chunker.rb +16 -2
- data/lib/lhm/sql_helper.rb +1 -1
- data/lib/lhm/throttler/time.rb +33 -0
- data/lib/lhm/version.rb +1 -1
- data/spec/integration/chunker_spec.rb +75 -0
- data/spec/integration/lhm_spec.rb +7 -14
- data/spec/unit/throttler_spec.rb +60 -0
- metadata +5 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9b9ff81249ed6289557c131a6b6183dd77b494af67b71cb4845e69628092801e
|
|
4
|
+
data.tar.gz: ca4a71a59985f62685056833ad288a63ff33b0ca233a7a41571cb7f0963b096e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ae9eedad45c7425785150927537a604084c60215c1bdfa796e7bc018fdddbaff2e431af97f5611d15ad5064ad9640f4af38c24f44712eb3567a66bba9f128038
|
|
7
|
+
data.tar.gz: 67135252c34441946ff069a1c6283545656a60b77306f8e6c019d319f0a164fd17dd898a21fcbfeba5490a52598812a804de52ad5fa498b6eee77a7731bc49ae
|
data/.github/workflows/test.yml
CHANGED
|
@@ -13,9 +13,10 @@ jobs:
|
|
|
13
13
|
|
|
14
14
|
strategy:
|
|
15
15
|
fail-fast: false
|
|
16
|
+
max-parallel: 8
|
|
16
17
|
matrix:
|
|
17
|
-
activerecord: ["6.1", "7.0", "7.1"]
|
|
18
|
-
ruby: ["3.
|
|
18
|
+
activerecord: ["6.1", "7.0", "7.1", "head"]
|
|
19
|
+
ruby: ["3.1", "3.2", "3.3", "head"]
|
|
19
20
|
mysql: ["5.7", "8.0"]
|
|
20
21
|
adapter: ["mysql2", "trilogy"]
|
|
21
22
|
exclude:
|
|
@@ -23,6 +24,8 @@ jobs:
|
|
|
23
24
|
ruby: head
|
|
24
25
|
- activerecord: 7.0
|
|
25
26
|
ruby: head
|
|
27
|
+
- activerecord: head
|
|
28
|
+
ruby: 3.0
|
|
26
29
|
|
|
27
30
|
env:
|
|
28
31
|
BUNDLE_GEMFILE: "${{ github.workspace }}/gemfiles/activerecord_${{ matrix.activerecord }}.gemfile"
|
|
@@ -40,7 +43,7 @@ jobs:
|
|
|
40
43
|
|
|
41
44
|
- name: Setup MySQL and ProxySQL (docker-compose)
|
|
42
45
|
# Might have to change to docker compose up -d (i.e. Compose V2) when the Ubuntu image changes the docker-compose version
|
|
43
|
-
run: docker
|
|
46
|
+
run: docker compose -f docker-compose-mysql-${{ matrix.mysql }}.yml up -d
|
|
44
47
|
|
|
45
48
|
- name: Wait until DBs are alive
|
|
46
49
|
run: ./scripts/helpers/wait-for-dbs.sh
|
data/Appraisals
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Unreleased
|
|
2
2
|
|
|
3
|
+
# 4.4.0 (Aug, 2024)
|
|
4
|
+
* Add support for retrying chunks when running into max_binlog_cache_size exceeded error
|
|
5
|
+
|
|
6
|
+
# 4.3.0 (Aug, 2024)
|
|
7
|
+
* Drop support for Ruby 3.0, as it reached its EOL
|
|
8
|
+
* Add support for next Rails version
|
|
9
|
+
|
|
3
10
|
# 4.2.3 (Jul, 2024)
|
|
4
11
|
* Fix check for warnings against PKs with line breaks
|
|
5
12
|
|
data/Gemfile.lock
CHANGED
|
@@ -1,61 +1,62 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
lhm-shopify (4.
|
|
4
|
+
lhm-shopify (4.4.0)
|
|
5
5
|
retriable (>= 3.0.0)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
8
8
|
remote: https://rubygems.org/
|
|
9
9
|
specs:
|
|
10
|
-
activemodel (7.
|
|
11
|
-
activesupport (= 7.
|
|
12
|
-
activerecord (7.
|
|
13
|
-
activemodel (= 7.
|
|
14
|
-
activesupport (= 7.
|
|
10
|
+
activemodel (7.2.0)
|
|
11
|
+
activesupport (= 7.2.0)
|
|
12
|
+
activerecord (7.2.0)
|
|
13
|
+
activemodel (= 7.2.0)
|
|
14
|
+
activesupport (= 7.2.0)
|
|
15
15
|
timeout (>= 0.4.0)
|
|
16
|
-
activesupport (7.
|
|
16
|
+
activesupport (7.2.0)
|
|
17
17
|
base64
|
|
18
18
|
bigdecimal
|
|
19
|
-
concurrent-ruby (~> 1.0, >= 1.
|
|
19
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
|
20
20
|
connection_pool (>= 2.2.5)
|
|
21
21
|
drb
|
|
22
22
|
i18n (>= 1.6, < 2)
|
|
23
|
+
logger (>= 1.4.2)
|
|
23
24
|
minitest (>= 5.1)
|
|
24
|
-
|
|
25
|
-
tzinfo (~> 2.0)
|
|
25
|
+
securerandom (>= 0.3)
|
|
26
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
|
26
27
|
after_do (0.4.0)
|
|
27
28
|
appraisal (2.5.0)
|
|
28
29
|
bundler
|
|
29
30
|
rake
|
|
30
31
|
thor (>= 0.14.0)
|
|
31
|
-
base64 (0.
|
|
32
|
-
bigdecimal (3.1.
|
|
32
|
+
base64 (0.2.0)
|
|
33
|
+
bigdecimal (3.1.8)
|
|
33
34
|
byebug (11.1.3)
|
|
34
|
-
concurrent-ruby (1.
|
|
35
|
+
concurrent-ruby (1.3.4)
|
|
35
36
|
connection_pool (2.4.1)
|
|
36
|
-
docile (1.4.
|
|
37
|
-
drb (2.
|
|
38
|
-
|
|
39
|
-
i18n (1.14.1)
|
|
37
|
+
docile (1.4.1)
|
|
38
|
+
drb (2.2.1)
|
|
39
|
+
i18n (1.14.5)
|
|
40
40
|
concurrent-ruby (~> 1.0)
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
logger (1.6.0)
|
|
42
|
+
minitest (5.25.1)
|
|
43
|
+
mocha (2.4.5)
|
|
43
44
|
ruby2_keywords (>= 0.0.5)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
rake (13.0.6)
|
|
45
|
+
mysql2 (0.5.6)
|
|
46
|
+
rake (13.2.1)
|
|
47
47
|
retriable (3.1.2)
|
|
48
48
|
ruby2_keywords (0.0.5)
|
|
49
|
+
securerandom (0.3.1)
|
|
49
50
|
simplecov (0.22.0)
|
|
50
51
|
docile (~> 1.1)
|
|
51
52
|
simplecov-html (~> 0.11)
|
|
52
53
|
simplecov_json_formatter (~> 0.1)
|
|
53
54
|
simplecov-html (0.12.3)
|
|
54
55
|
simplecov_json_formatter (0.1.4)
|
|
55
|
-
thor (1.
|
|
56
|
-
timeout (0.4.
|
|
56
|
+
thor (1.3.1)
|
|
57
|
+
timeout (0.4.1)
|
|
57
58
|
toxiproxy (2.0.2)
|
|
58
|
-
trilogy (2.
|
|
59
|
+
trilogy (2.8.1)
|
|
59
60
|
tzinfo (2.0.6)
|
|
60
61
|
concurrent-ruby (~> 1.0)
|
|
61
62
|
|
data/dev.yml
CHANGED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
GIT
|
|
2
|
+
remote: https://github.com/rails/rails.git
|
|
3
|
+
revision: f4a9b7618fc32f0d3b2c0ff03a3f34f4964cc553
|
|
4
|
+
branch: main
|
|
5
|
+
specs:
|
|
6
|
+
activemodel (8.0.0.alpha)
|
|
7
|
+
activesupport (= 8.0.0.alpha)
|
|
8
|
+
activerecord (8.0.0.alpha)
|
|
9
|
+
activemodel (= 8.0.0.alpha)
|
|
10
|
+
activesupport (= 8.0.0.alpha)
|
|
11
|
+
timeout (>= 0.4.0)
|
|
12
|
+
activesupport (8.0.0.alpha)
|
|
13
|
+
base64
|
|
14
|
+
bigdecimal
|
|
15
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
|
16
|
+
connection_pool (>= 2.2.5)
|
|
17
|
+
drb
|
|
18
|
+
i18n (>= 1.6, < 2)
|
|
19
|
+
logger (>= 1.4.2)
|
|
20
|
+
minitest (>= 5.1)
|
|
21
|
+
securerandom (>= 0.3)
|
|
22
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
|
23
|
+
|
|
24
|
+
PATH
|
|
25
|
+
remote: ..
|
|
26
|
+
specs:
|
|
27
|
+
lhm-shopify (4.4.0)
|
|
28
|
+
retriable (>= 3.0.0)
|
|
29
|
+
|
|
30
|
+
GEM
|
|
31
|
+
remote: https://rubygems.org/
|
|
32
|
+
specs:
|
|
33
|
+
after_do (0.4.0)
|
|
34
|
+
appraisal (2.5.0)
|
|
35
|
+
bundler
|
|
36
|
+
rake
|
|
37
|
+
thor (>= 0.14.0)
|
|
38
|
+
base64 (0.2.0)
|
|
39
|
+
bigdecimal (3.1.8)
|
|
40
|
+
byebug (11.1.3)
|
|
41
|
+
concurrent-ruby (1.3.3)
|
|
42
|
+
connection_pool (2.4.1)
|
|
43
|
+
docile (1.4.1)
|
|
44
|
+
drb (2.2.1)
|
|
45
|
+
i18n (1.14.5)
|
|
46
|
+
concurrent-ruby (~> 1.0)
|
|
47
|
+
logger (1.6.0)
|
|
48
|
+
minitest (5.24.1)
|
|
49
|
+
mocha (2.4.5)
|
|
50
|
+
ruby2_keywords (>= 0.0.5)
|
|
51
|
+
mysql2 (0.5.6)
|
|
52
|
+
rake (13.2.1)
|
|
53
|
+
retriable (3.1.2)
|
|
54
|
+
ruby2_keywords (0.0.5)
|
|
55
|
+
securerandom (0.3.1)
|
|
56
|
+
simplecov (0.22.0)
|
|
57
|
+
docile (~> 1.1)
|
|
58
|
+
simplecov-html (~> 0.11)
|
|
59
|
+
simplecov_json_formatter (~> 0.1)
|
|
60
|
+
simplecov-html (0.12.3)
|
|
61
|
+
simplecov_json_formatter (0.1.4)
|
|
62
|
+
thor (1.3.1)
|
|
63
|
+
timeout (0.4.1)
|
|
64
|
+
toxiproxy (2.0.2)
|
|
65
|
+
trilogy (2.8.1)
|
|
66
|
+
tzinfo (2.0.6)
|
|
67
|
+
concurrent-ruby (~> 1.0)
|
|
68
|
+
|
|
69
|
+
PLATFORMS
|
|
70
|
+
arm64-darwin-22
|
|
71
|
+
x86_64-linux
|
|
72
|
+
|
|
73
|
+
DEPENDENCIES
|
|
74
|
+
activerecord!
|
|
75
|
+
after_do
|
|
76
|
+
appraisal
|
|
77
|
+
byebug
|
|
78
|
+
lhm-shopify!
|
|
79
|
+
minitest
|
|
80
|
+
mocha
|
|
81
|
+
mysql2
|
|
82
|
+
rake
|
|
83
|
+
simplecov
|
|
84
|
+
toxiproxy
|
|
85
|
+
trilogy
|
|
86
|
+
|
|
87
|
+
BUNDLED WITH
|
|
88
|
+
2.2.22
|
data/lib/lhm/chunker.rb
CHANGED
|
@@ -37,6 +37,10 @@ module Lhm
|
|
|
37
37
|
)
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
+
def handle_max_binlog_exceeded_error
|
|
41
|
+
@throttler.backoff_stride
|
|
42
|
+
end
|
|
43
|
+
|
|
40
44
|
def execute
|
|
41
45
|
@start_time = Time.now
|
|
42
46
|
|
|
@@ -47,7 +51,18 @@ module Lhm
|
|
|
47
51
|
top = upper_id(@next_to_insert, stride)
|
|
48
52
|
verify_can_run
|
|
49
53
|
|
|
50
|
-
|
|
54
|
+
begin
|
|
55
|
+
affected_rows = ChunkInsert.new(@migration, @connection, bottom, top, @retry_options).insert_and_return_count_of_rows_created
|
|
56
|
+
rescue ActiveRecord::StatementInvalid => e
|
|
57
|
+
if e.message.downcase.include?("transaction required more than 'max_binlog_cache_size' bytes of storage")
|
|
58
|
+
Lhm.logger.info("Encountered max_binlog_cache_size error, attempting to reduce stride size")
|
|
59
|
+
handle_max_binlog_exceeded_error
|
|
60
|
+
next
|
|
61
|
+
else
|
|
62
|
+
raise e
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
51
66
|
expected_rows = top - bottom + 1
|
|
52
67
|
|
|
53
68
|
# Only log the chunker progress every 5 minutes instead of every iteration
|
|
@@ -110,6 +125,5 @@ module Lhm
|
|
|
110
125
|
return if @chunk_finder.table_empty?
|
|
111
126
|
@chunk_finder.validate
|
|
112
127
|
end
|
|
113
|
-
|
|
114
128
|
end
|
|
115
129
|
end
|
data/lib/lhm/sql_helper.rb
CHANGED
data/lib/lhm/throttler/time.rb
CHANGED
|
@@ -5,6 +5,8 @@ module Lhm
|
|
|
5
5
|
|
|
6
6
|
DEFAULT_TIMEOUT = 0.1
|
|
7
7
|
DEFAULT_STRIDE = 2_000
|
|
8
|
+
DEFAULT_BACKOFF_REDUCTION_FACTOR = 0.2 # 20%
|
|
9
|
+
MIN_STRIDE_SIZE = 1
|
|
8
10
|
|
|
9
11
|
attr_accessor :timeout_seconds
|
|
10
12
|
attr_accessor :stride
|
|
@@ -12,6 +14,37 @@ module Lhm
|
|
|
12
14
|
def initialize(options = {})
|
|
13
15
|
@timeout_seconds = options[:delay] || DEFAULT_TIMEOUT
|
|
14
16
|
@stride = options[:stride] || DEFAULT_STRIDE
|
|
17
|
+
@backoff_reduction_factor = options[:backoff_reduction_factor] || DEFAULT_BACKOFF_REDUCTION_FACTOR
|
|
18
|
+
@min_stride_size = options[:min_stride_size] || MIN_STRIDE_SIZE
|
|
19
|
+
|
|
20
|
+
if @backoff_reduction_factor >= 1 || @backoff_reduction_factor <= 0
|
|
21
|
+
raise ArgumentError, 'backoff_reduction_factor must be between greater than 0, and less than 1'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
if @min_stride_size < 1
|
|
25
|
+
raise ArgumentError, 'min_stride_size must be an integer greater than 0'
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
if !@min_stride_size.is_a?(Integer)
|
|
29
|
+
raise ArgumentError, 'min_stride_size must be an integer'
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
if @min_stride_size > @stride
|
|
33
|
+
raise ArgumentError, 'min_stride_size must be less than or equal to stride'
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def backoff_stride
|
|
38
|
+
new_stride = (@stride * (1 - @backoff_reduction_factor)).to_i
|
|
39
|
+
|
|
40
|
+
if new_stride == @stride
|
|
41
|
+
raise RuntimeError, "Cannot backoff any further"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
if new_stride < @min_stride_size
|
|
45
|
+
raise RuntimeError, "Cannot reduce stride below #{@min_stride_size}"
|
|
46
|
+
end
|
|
47
|
+
@stride = new_stride
|
|
15
48
|
end
|
|
16
49
|
|
|
17
50
|
def execute
|
data/lib/lhm/version.rb
CHANGED
|
@@ -5,6 +5,7 @@ require File.expand_path(File.dirname(__FILE__)) + '/integration_helper'
|
|
|
5
5
|
require 'lhm/table'
|
|
6
6
|
require 'lhm/migration'
|
|
7
7
|
|
|
8
|
+
|
|
8
9
|
describe Lhm::Chunker do
|
|
9
10
|
include IntegrationHelper
|
|
10
11
|
|
|
@@ -17,6 +18,7 @@ describe Lhm::Chunker do
|
|
|
17
18
|
@migration = Lhm::Migration.new(@origin, @destination)
|
|
18
19
|
@logs = StringIO.new
|
|
19
20
|
Lhm.logger = Logger.new(@logs)
|
|
21
|
+
set_max_binlog_size(1024 * 1024 * 1024) # necessary since some tests reduce binlog size (1gb default)
|
|
20
22
|
end
|
|
21
23
|
|
|
22
24
|
def log_messages
|
|
@@ -306,6 +308,70 @@ describe Lhm::Chunker do
|
|
|
306
308
|
value(count_all(@destination.name)).must_equal(0)
|
|
307
309
|
end
|
|
308
310
|
end
|
|
311
|
+
|
|
312
|
+
it 'should reduce stride size if chunker runs into max_binlog_cache_size error' do
|
|
313
|
+
init_stride = 1000
|
|
314
|
+
|
|
315
|
+
# Create a bunch of users
|
|
316
|
+
n = 0
|
|
317
|
+
25.times do |i|
|
|
318
|
+
execute "BEGIN"
|
|
319
|
+
init_stride.times do # each batch is 10 * 1000 * i bytes, so each batch of 1000 will range from 10kb - 250kb
|
|
320
|
+
n += 1
|
|
321
|
+
id = n
|
|
322
|
+
username_data = "a" * 10 * i
|
|
323
|
+
execute "insert into origin (id, common) values (#{id}, '#{username_data}')"
|
|
324
|
+
end
|
|
325
|
+
execute "COMMIT"
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
# reduce binlog size to 8kb
|
|
329
|
+
set_max_binlog_size(1024 * 8)
|
|
330
|
+
|
|
331
|
+
throttler = Lhm::Throttler::Time.new(stride: init_stride )
|
|
332
|
+
chunker = Lhm::Chunker.new(
|
|
333
|
+
@migration, connection, { throttler: throttler }
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
# start chunking
|
|
337
|
+
chunker.run
|
|
338
|
+
assert init_stride > throttler.stride
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
it 'should throw an error when stride cannot be reduced beyond min stride size' do
|
|
342
|
+
init_stride = 100
|
|
343
|
+
min_stride_size = 50
|
|
344
|
+
|
|
345
|
+
# Create a bunch of users
|
|
346
|
+
n = 0
|
|
347
|
+
25.times do |i|
|
|
348
|
+
execute "BEGIN"
|
|
349
|
+
init_stride.times do # each batch is init_stride * 250 bytes, so even at min_stride of 20,
|
|
350
|
+
# batch_size will be greater than 4kb (50 * 250kb = 12.5kb)
|
|
351
|
+
n += 1
|
|
352
|
+
id = n
|
|
353
|
+
username_data = "a" * 250
|
|
354
|
+
execute "insert into origin (id, common) values (#{id}, '#{username_data}')"
|
|
355
|
+
end
|
|
356
|
+
execute "COMMIT"
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
# reduce binlog size to 4kb
|
|
360
|
+
set_max_binlog_size(1024 * 4)
|
|
361
|
+
throttler = Lhm::Throttler::Time.new(stride: init_stride, min_stride_size: min_stride_size, backoff_reduction_factor: 0.9)
|
|
362
|
+
|
|
363
|
+
chunker = Lhm::Chunker.new(
|
|
364
|
+
@migration, connection, { throttler: throttler }
|
|
365
|
+
)
|
|
366
|
+
|
|
367
|
+
# start chunking
|
|
368
|
+
exception = assert_raises do
|
|
369
|
+
chunker.run
|
|
370
|
+
end
|
|
371
|
+
|
|
372
|
+
assert RuntimeError = exception.class
|
|
373
|
+
assert "Cannot reduce stride below #{min_stride_size}" == exception.message
|
|
374
|
+
end
|
|
309
375
|
end
|
|
310
376
|
|
|
311
377
|
def index_key(table_name, index_name)
|
|
@@ -315,4 +381,13 @@ describe Lhm::Chunker do
|
|
|
315
381
|
index_name
|
|
316
382
|
end
|
|
317
383
|
end
|
|
384
|
+
|
|
385
|
+
def set_global_variable(name, value)
|
|
386
|
+
execute("set global #{name} = #{value}")
|
|
387
|
+
connection.reconnect!
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
def set_max_binlog_size(value)
|
|
391
|
+
set_global_variable('max_binlog_cache_size', value)
|
|
392
|
+
end
|
|
318
393
|
end
|
|
@@ -328,8 +328,7 @@ describe Lhm do
|
|
|
328
328
|
:collate => collation,
|
|
329
329
|
})
|
|
330
330
|
|
|
331
|
-
result =
|
|
332
|
-
result = result['login'] if result.respond_to?(:has_key?)
|
|
331
|
+
result = select_value('SELECT login from users')
|
|
333
332
|
value(result).must_equal('a user')
|
|
334
333
|
end
|
|
335
334
|
end
|
|
@@ -353,8 +352,7 @@ describe Lhm do
|
|
|
353
352
|
:collate => collation,
|
|
354
353
|
})
|
|
355
354
|
|
|
356
|
-
result =
|
|
357
|
-
result = result['fnord'] if result.respond_to?(:has_key?)
|
|
355
|
+
result = select_value('SELECT `fnord` from users')
|
|
358
356
|
value(result).must_equal('Superfriends')
|
|
359
357
|
end
|
|
360
358
|
end
|
|
@@ -380,8 +378,7 @@ describe Lhm do
|
|
|
380
378
|
:collate => 'utf8mb4_unicode_ci',
|
|
381
379
|
})
|
|
382
380
|
|
|
383
|
-
result =
|
|
384
|
-
result = result['user_name'] if result.respond_to?(:has_key?)
|
|
381
|
+
result = select_value('SELECT `user_name` from users')
|
|
385
382
|
value(result).must_equal('a user')
|
|
386
383
|
end
|
|
387
384
|
end
|
|
@@ -410,8 +407,7 @@ describe Lhm do
|
|
|
410
407
|
:collate => nil,
|
|
411
408
|
})
|
|
412
409
|
|
|
413
|
-
result =
|
|
414
|
-
result = result['ref'] if result.respond_to?(:has_key?)
|
|
410
|
+
result = select_value('SELECT `ref` from users')
|
|
415
411
|
value(result).must_equal(10)
|
|
416
412
|
end
|
|
417
413
|
end
|
|
@@ -437,8 +433,7 @@ describe Lhm do
|
|
|
437
433
|
:collate => collation,
|
|
438
434
|
})
|
|
439
435
|
|
|
440
|
-
result =
|
|
441
|
-
result = result['fnord'] if result.respond_to?(:has_key?)
|
|
436
|
+
result = select_value('SELECT `fnord` from users')
|
|
442
437
|
assert_nil(result)
|
|
443
438
|
end
|
|
444
439
|
end
|
|
@@ -462,8 +457,7 @@ describe Lhm do
|
|
|
462
457
|
:collate => collation,
|
|
463
458
|
})
|
|
464
459
|
|
|
465
|
-
result =
|
|
466
|
-
result = result['user_name'] if result.respond_to?(:has_key?)
|
|
460
|
+
result = select_value('SELECT `user_name` from users')
|
|
467
461
|
value(result).must_equal('a user')
|
|
468
462
|
end
|
|
469
463
|
end
|
|
@@ -489,8 +483,7 @@ describe Lhm do
|
|
|
489
483
|
:collate => collation,
|
|
490
484
|
})
|
|
491
485
|
|
|
492
|
-
result =
|
|
493
|
-
result = result['user_name'] if result.respond_to?(:has_key?)
|
|
486
|
+
result = select_value('SELECT `user_name` from users')
|
|
494
487
|
value(result).must_equal('a user')
|
|
495
488
|
end
|
|
496
489
|
end
|
data/spec/unit/throttler_spec.rb
CHANGED
|
@@ -111,6 +111,66 @@ describe Lhm::Throttler do
|
|
|
111
111
|
end
|
|
112
112
|
end
|
|
113
113
|
|
|
114
|
+
describe 'when using backoff functionality' do
|
|
115
|
+
it 'should backoff by default amount' do
|
|
116
|
+
@mock.setup_throttler(:time_throttler, stride: 100)
|
|
117
|
+
@mock.throttler.backoff_stride
|
|
118
|
+
value(@mock.throttler.stride).must_equal 80
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it 'should backoff by specified amount' do
|
|
122
|
+
@mock.setup_throttler(:time_throttler, backoff_reduction_factor: 0.5, stride: 100)
|
|
123
|
+
@mock.throttler.backoff_stride
|
|
124
|
+
value(@mock.throttler.stride).must_equal 50
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
it 'should throw an error when backoff exceeds limit' do
|
|
128
|
+
@mock.setup_throttler(:time_throttler, backoff_reduction_factor: 0.2, stride: 1000, min_stride_size: 900)
|
|
129
|
+
proc { @mock.throttler.backoff_stride }.must_raise RuntimeError
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
it 'should throw an error when backoff cannot be done anymore' do
|
|
133
|
+
@mock.setup_throttler(:time_throttler, backoff_reduction_factor: 0.2, stride: 1, min_stride_size: 1)
|
|
134
|
+
proc { @mock.throttler.backoff_stride }.must_raise RuntimeError
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it 'should throw an error when backoff reduction factor is not less than one' do
|
|
138
|
+
assert_raises ArgumentError do
|
|
139
|
+
@mock.setup_throttler(:time_throttler, backoff_reduction_factor: 1)
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
it 'should throw an error when backoff reduction factor is not greater than zero' do
|
|
144
|
+
assert_raises ArgumentError do
|
|
145
|
+
@mock.setup_throttler(:time_throttler, backoff_reduction_factor: 0)
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
it 'should throw an error when backoff reduction factor is negative' do
|
|
150
|
+
assert_raises ArgumentError do
|
|
151
|
+
@mock.setup_throttler(:time_throttler, backoff_reduction_factor: -0.5)
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
it 'should throw an error when min_stride_size is not an integer' do
|
|
156
|
+
assert_raises ArgumentError do
|
|
157
|
+
@mock.setup_throttler(:time_throttler, min_stride_size: 0.5)
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
it 'should throw an error when min_stride_size is not greater than 1' do
|
|
162
|
+
assert_raises ArgumentError do
|
|
163
|
+
@mock.setup_throttler(:time_throttler, min_stride_size: -12)
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
it 'should throw an error when min_stride_size is greater than inital stride size' do
|
|
168
|
+
assert_raises ArgumentError do
|
|
169
|
+
@mock.setup_throttler(:time_throttler, min_stride_size: 1000, stride: 500)
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
|
|
114
174
|
describe '#throttler' do
|
|
115
175
|
|
|
116
176
|
it 'returns the default Time based' do
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lhm-shopify
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.
|
|
4
|
+
version: 4.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- SoundCloud
|
|
@@ -12,7 +12,7 @@ authors:
|
|
|
12
12
|
autorequire:
|
|
13
13
|
bindir: bin
|
|
14
14
|
cert_chain: []
|
|
15
|
-
date: 2024-
|
|
15
|
+
date: 2024-08-20 00:00:00.000000000 Z
|
|
16
16
|
dependencies:
|
|
17
17
|
- !ruby/object:Gem::Dependency
|
|
18
18
|
name: retriable
|
|
@@ -212,6 +212,8 @@ files:
|
|
|
212
212
|
- gemfiles/activerecord_7.0.gemfile.lock
|
|
213
213
|
- gemfiles/activerecord_7.1.gemfile
|
|
214
214
|
- gemfiles/activerecord_7.1.gemfile.lock
|
|
215
|
+
- gemfiles/activerecord_head.gemfile
|
|
216
|
+
- gemfiles/activerecord_head.gemfile.lock
|
|
215
217
|
- lhm.gemspec
|
|
216
218
|
- lib/lhm-shopify.rb
|
|
217
219
|
- lib/lhm.rb
|
|
@@ -324,7 +326,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
324
326
|
- !ruby/object:Gem::Version
|
|
325
327
|
version: '0'
|
|
326
328
|
requirements: []
|
|
327
|
-
rubygems_version: 3.5.
|
|
329
|
+
rubygems_version: 3.5.17
|
|
328
330
|
signing_key:
|
|
329
331
|
specification_version: 4
|
|
330
332
|
summary: online schema changer for mysql
|