Class: Apartment::Migrator

Inherits:
Object
  • Object
show all
Defined in:
lib/apartment/migrator.rb

Overview

rubocop:disable Metrics/ClassLength

Defined Under Namespace

Classes: MigrationRun, Result

Constant Summary collapse

ADVISORY_LOCKS_IVAR =

ActiveRecord exposes no public setter for advisory-lock state (only the advisory_locks_enabled? reader), so we toggle this private ivar directly. The guard in with_advisory_locks_disabled detects a future Rails rename.

:@advisory_locks_enabled

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(threads: 0, version: nil) ⇒ Migrator

Returns a new instance of Migrator.



52
53
54
55
# File 'lib/apartment/migrator.rb', line 52

def initialize(threads: 0, version: nil)
  @threads = threads
  @version = version
end

Class Method Details

.with_migration_roleObject

Wrap a block in connected_to(role: ddl_role) when configured. Class method so both Migrator internals and CLI commands can share the same RBAC role-switching logic without duplication. The adapters need it too (tenant creation is DDL), and they cannot depend on Migrator, so the implementation lives in Apartment::MigrationRole.



50
# File 'lib/apartment/migrator.rb', line 50

def self.with_migration_role(&) = Apartment::MigrationRole.wrap(&)

Instance Method Details

#migrate_one(tenant) ⇒ Object

Migrate a single named tenant. Returns a Result. Evicts migration-role pools in ensure regardless of outcome.



90
91
92
93
94
# File 'lib/apartment/migrator.rb', line 90

def migrate_one(tenant)
  migrate_tenant(tenant)
ensure
  evict_migration_pools
end

#runObject

rubocop:disable Metrics/MethodLength



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/apartment/migrator.rb', line 57

def run # rubocop:disable Metrics/MethodLength
  start = monotonic_now

  primary_result = with_migration_role { migrate_primary }

  if primary_result.status == :failed
    return MigrationRun.new(
      results: [primary_result],
      total_duration: monotonic_now - start,
      threads: @threads
    )
  end

  tenants = Apartment.tenant_names
  tenant_results = if @threads.positive?
                     run_parallel(tenants)
                   else
                     run_sequential(tenants)
                   end

  all_results = [primary_result, *tenant_results].compact

  MigrationRun.new(
    results: all_results,
    total_duration: monotonic_now - start,
    threads: @threads
  )
ensure
  evict_migration_pools
end