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.



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

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

Class Method Details

.with_migration_roleObject

Wrap a block in connected_to(role: migration_role) when configured. Class method so both Migrator internals and CLI commands can share the same RBAC role-switching logic without duplication.



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

def self.with_migration_role(&)
  role = Apartment.config.migration_role
  role ? ActiveRecord::Base.connected_to(role: role, &) : yield
end

Instance Method Details

#migrate_one(tenant) ⇒ Object

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



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

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

#runObject

rubocop:disable Metrics/MethodLength



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
87
# File 'lib/apartment/migrator.rb', line 58

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