nandi 3.1.0 → 3.2.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
  SHA256:
3
- metadata.gz: ea1c9b758014a99ea83562525b13d80c54ed0dd310ffd64eaebae6009235cebf
4
- data.tar.gz: 77d9ae338cd152b213acaa18c2e6ba6ecbe56f7f1fe955264694d98d8b526030
3
+ metadata.gz: '068eff75d4f385070e3da2d3738019cf4e6be7554a16e235f3701e3c0db79419'
4
+ data.tar.gz: cfe9e766d00073ab040888cad17bedb8c4b2b294d7e353d5298a9ccce9a130f2
5
5
  SHA512:
6
- metadata.gz: c3b1935d279ba467262f79d7153ad5cfe1741da7d6c42ba618dd038f7216cc32435403343ad3adfde4e800953658cf5c8db75ab5b2fc434faef54d6871b4081b
7
- data.tar.gz: 0c71da4c6691fe6e3b75acaa32c23af55b32c4b94ce3a7e7afc2021e98f2c64ba1aeb19e7da9a182ba0584c716fec3a725d1dff7ce7c789c49bb18f2a8cf170b
6
+ metadata.gz: 86c97f9217b2fc3819d8204f80e0f29d7d00e63b3929b40cd684d66b6e701d97b69bb1094714ef8e33bf3c451d67fb31803a18c6625ac2f2a06e4c159ff2dd98
7
+ data.tar.gz: 83b8831e08ddcfedf0e558acf5b4813866605757f17d3ca74ec21f9815f774f8207d0b2e7dd1d50aa87674c39e06420fac106454996b2a8f37eb4a660a6e1b95
data/README.md CHANGED
@@ -566,6 +566,9 @@ These options can be set individually for each database. **All are optional** -
566
566
  - `access_exclusive_statement_timeout_limit`: Maximum allowed statement timeout (default: 1,500ms)
567
567
  - `concurrent_lock_timeout_limit`: Minimum timeout for concurrent operations (default: 3,600,000ms / 1 hour)
568
568
  - `concurrent_statement_timeout_limit`: Minimum statement timeout for concurrent operations (default: 3,600,000ms / 1 hour)
569
+ - `concurrent_lock_timeout`: Lock timeout for concurrent operations (`add_index`/`remove_index`). When set, concurrent migrations use `set_lock_timeout` instead of `disable_lock_timeout!`. Default: `nil` (timeout disabled)
570
+ - `concurrent_statement_timeout`: Statement timeout for concurrent operations. When set, concurrent migrations use `set_statement_timeout` instead of `disable_statement_timeout!`. Default: `nil` (timeout disabled)
571
+ - `table_overrides`: Per-table overrides of `concurrent_lock_timeout`/`concurrent_statement_timeout`, keyed by table name. Falls back to the database-level value for any table (or key) not listed
569
572
 
570
573
  **Global options** (set via config accessors):
571
574
 
@@ -621,6 +624,20 @@ Nandi.configure do |config|
621
624
  migration
622
625
  end
623
626
  end
627
+
628
+ # Give a specific, huge table a longer concurrent statement/lock timeout than
629
+ # the database-wide default, without loosening it for every other table.
630
+ Nandi.configure do |config|
631
+ config.register_database(:primary,
632
+ concurrent_lock_timeout: 120_000, # 2 minutes, database-wide default
633
+ concurrent_statement_timeout: 600_000, # 10 minutes, database-wide default
634
+ table_overrides: {
635
+ payments: {
636
+ concurrent_lock_timeout: 300_000, # 5 minutes
637
+ concurrent_statement_timeout: 1_800_000, # 30 minutes
638
+ },
639
+ })
640
+ end
624
641
  ```
625
642
 
626
643
  ### Directory Structure
data/lib/nandi/config.rb CHANGED
@@ -84,8 +84,8 @@ module Nandi
84
84
  def access_exclusive_statement_timeout_max(database_name = nil) = config(database_name).access_exclusive_statement_timeout_max
85
85
  def concurrent_lock_timeout_min(database_name = nil) = config(database_name).concurrent_lock_timeout_min
86
86
  def concurrent_statement_timeout_min(database_name = nil) = config(database_name).concurrent_statement_timeout_min
87
- def concurrent_lock_timeout(database_name = nil) = config(database_name).concurrent_lock_timeout
88
- def concurrent_statement_timeout(database_name = nil) = config(database_name).concurrent_statement_timeout
87
+ def concurrent_lock_timeout(database_name = nil, table_name = nil) = config(database_name).concurrent_lock_timeout(table_name)
88
+ def concurrent_statement_timeout(database_name = nil, table_name = nil) = config(database_name).concurrent_statement_timeout(table_name)
89
89
  # rubocop:enable Layout/LineLength
90
90
 
91
91
  # Delegate setter methods to the default database for backwards compatibility
@@ -337,7 +337,7 @@ module Nandi
337
337
 
338
338
  def disable_lock_timeout?
339
339
  if self.class.lock_timeout.nil?
340
- strictest_lock == LockWeights::SHARE && Nandi.config.concurrent_lock_timeout(database_name).nil?
340
+ strictest_lock == LockWeights::SHARE && Nandi.config.concurrent_lock_timeout(database_name, table).nil?
341
341
  else
342
342
  false
343
343
  end
@@ -345,7 +345,7 @@ module Nandi
345
345
 
346
346
  def disable_statement_timeout?
347
347
  if self.class.statement_timeout.nil?
348
- strictest_lock == LockWeights::SHARE && Nandi.config.concurrent_statement_timeout(database_name).nil?
348
+ strictest_lock == LockWeights::SHARE && Nandi.config.concurrent_statement_timeout(database_name, table).nil?
349
349
  else
350
350
  false
351
351
  end
@@ -360,7 +360,7 @@ module Nandi
360
360
  end
361
361
 
362
362
  def mixins
363
- (up_instructions + down_instructions).inject([]) do |mixins, i|
363
+ all_instructions.inject([]) do |mixins, i|
364
364
  i.respond_to?(:mixins) ? [*mixins, *i.mixins] : mixins
365
365
  end.uniq
366
366
  end
@@ -383,7 +383,7 @@ module Nandi
383
383
 
384
384
  def default_statement_timeout
385
385
  if strictest_lock == LockWeights::SHARE
386
- Nandi.config.concurrent_statement_timeout(database_name) ||
386
+ Nandi.config.concurrent_statement_timeout(database_name, table) ||
387
387
  Nandi.config.access_exclusive_statement_timeout(database_name)
388
388
  else
389
389
  Nandi.config.access_exclusive_statement_timeout(database_name)
@@ -392,12 +392,24 @@ module Nandi
392
392
 
393
393
  def default_lock_timeout
394
394
  if strictest_lock == LockWeights::SHARE
395
- Nandi.config.concurrent_lock_timeout(database_name) || Nandi.config.access_exclusive_lock_timeout(database_name)
395
+ Nandi.config.concurrent_lock_timeout(database_name, table) ||
396
+ Nandi.config.access_exclusive_lock_timeout(database_name)
396
397
  else
397
398
  Nandi.config.access_exclusive_lock_timeout(database_name)
398
399
  end
399
400
  end
400
401
 
402
+ # The table this migration modifies, if any. Validator guarantees a migration
403
+ # modifies at most one table, so this is unambiguous.
404
+ def table
405
+ instruction_with_table = all_instructions.find { |i| i.respond_to?(:table) }
406
+ instruction_with_table&.table&.to_sym
407
+ end
408
+
409
+ def all_instructions
410
+ up_instructions + down_instructions
411
+ end
412
+
401
413
  def invoke_custom_method(name, ...)
402
414
  klass = Nandi.config.custom_methods[name]
403
415
  current_instructions << klass.new(...)
@@ -54,14 +54,24 @@ module Nandi
54
54
  # The default lock timeout for migrations that take place concurrently
55
55
  # (eg. add_index, remove_index). When set, concurrent migrations will use
56
56
  # set_lock_timeout instead of disable_lock_timeout!. Default: nil (disabled).
57
+ # Can be overridden for a specific table via `table_overrides`.
58
+ # @param table_name [Symbol, String, nil]
57
59
  # @return [Integer, nil]
58
- attr_accessor :concurrent_lock_timeout
60
+ def concurrent_lock_timeout(table_name = nil)
61
+ table_override(table_name, :concurrent_lock_timeout) || @concurrent_lock_timeout
62
+ end
63
+ attr_writer :concurrent_lock_timeout
59
64
 
60
65
  # The default statement timeout for migrations that take place concurrently
61
66
  # (eg. add_index, remove_index). When set, concurrent migrations will use
62
67
  # set_statement_timeout instead of disable_statement_timeout!. Default: nil (disabled).
68
+ # Can be overridden for a specific table via `table_overrides`.
69
+ # @param table_name [Symbol, String, nil]
63
70
  # @return [Integer, nil]
64
- attr_accessor :concurrent_statement_timeout
71
+ def concurrent_statement_timeout(table_name = nil)
72
+ table_override(table_name, :concurrent_statement_timeout) || @concurrent_statement_timeout
73
+ end
74
+ attr_writer :concurrent_statement_timeout
65
75
 
66
76
  # The directory for output files. Default: `db/migrate`
67
77
  # @return [String]
@@ -121,6 +131,17 @@ module Nandi
121
131
  config[:concurrent_statement_timeout_min] || DEFAULT_CONCURRENT_STATEMENT_TIMEOUT_MIN
122
132
  @concurrent_lock_timeout = config[:concurrent_lock_timeout]
123
133
  @concurrent_statement_timeout = config[:concurrent_statement_timeout]
134
+ @table_overrides = normalize_table_overrides(config[:table_overrides])
135
+ end
136
+
137
+ def normalize_table_overrides(table_overrides)
138
+ (table_overrides || {}).transform_keys(&:to_sym)
139
+ end
140
+
141
+ def table_override(table_name, key)
142
+ return nil if table_name.nil?
143
+
144
+ @table_overrides.dig(table_name.to_sym, key)
124
145
  end
125
146
 
126
147
  def path_prefix(name, default)
data/lib/nandi/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Nandi
4
- VERSION = "3.1.0"
4
+ VERSION = "3.2.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nandi
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - GoCardless Engineering
@@ -180,7 +180,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
180
180
  - !ruby/object:Gem::Version
181
181
  version: '0'
182
182
  requirements: []
183
- rubygems_version: 4.0.10
183
+ rubygems_version: 4.0.9
184
184
  specification_version: 4
185
185
  summary: Fear-free migrations for PostgreSQL
186
186
  test_files: []