Module: Switchman::ActiveRecord::TestFixtures

Defined in:
lib/switchman/active_record/test_fixtures.rb

Constant Summary collapse

FORBIDDEN_DB_ENVS =
%i[development production].freeze

Instance Method Summary collapse

Instance Method Details

#enlist_fixture_connectionsObject



41
42
43
44
45
46
47
# File 'lib/switchman/active_record/test_fixtures.rb', line 41

def enlist_fixture_connections
  setup_shared_connection_pool

  ::ActiveRecord::Base.connection_handler.connection_pool_list(:primary).reject do |cp|
    FORBIDDEN_DB_ENVS.include?(cp.db_config.env_name.to_sym)
  end.map(&:connection)
end

#setup_fixtures(config = ::ActiveRecord::Base) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/switchman/active_record/test_fixtures.rb', line 9

def setup_fixtures(config = ::ActiveRecord::Base)
  super
  return unless run_in_transaction?

  # Replace the one that activerecord natively uses with a switchman-optimized one
  ::ActiveSupport::Notifications.unsubscribe(@connection_subscriber)
  # Code adapted from the code in rails proper
  @connection_subscriber =
    ::ActiveSupport::Notifications.subscribe("!connection.active_record") do |_, _, _, _, payload|
      spec_name = (payload[:connection_name] if payload.key?(:connection_name))
      shard = payload[:shard] if payload.key?(:shard)

      if spec_name && !FORBIDDEN_DB_ENVS.include?(shard)
        begin
          connection = ::ActiveRecord::Base.connection_handler.retrieve_connection(spec_name, shard: shard)
          connection.connect! # eagerly validate the connection
        rescue ::ActiveRecord::ConnectionNotEstablished
          connection = nil
        end

        if connection
          setup_shared_connection_pool
          unless @fixture_connections.include?(connection)
            connection.begin_transaction joinable: false, _lazy: false
            connection.pool.lock_thread = true if lock_threads
            @fixture_connections << connection
          end
        end
      end
    end
end

#setup_transactional_fixturesObject



49
50
51
52
53
54
55
56
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
# File 'lib/switchman/active_record/test_fixtures.rb', line 49

def setup_transactional_fixtures
  setup_shared_connection_pool

  # Begin transactions for connections already established
  # INST: :writing -> :primary
  @fixture_connection_pools = ::ActiveRecord::Base.connection_handler.connection_pool_list(:primary)
  # INST: filter by FORBIDDEN_DB_ENVS
  @fixture_connection_pools = @fixture_connection_pools.reject do |cp|
    FORBIDDEN_DB_ENVS.include?(cp.db_config.env_name.to_sym)
  end

  @fixture_connection_pools.each do |pool|
    pool.pin_connection!(lock_threads)
    pool.lease_connection
  end

  # When connections are established in the future, begin a transaction too
  @connection_subscriber = ::ActiveSupport::Notifications
                           .subscribe("!connection.active_record") do |_, _, _, _, payload|
    connection_name = payload[:connection_name] if payload.key?(:connection_name)
    shard = payload[:shard] if payload.key?(:shard)

    # INST: filter by FORBIDDEN_DB_ENVS
    if connection_name && !FORBIDDEN_DB_ENVS.include?(shard)
      pool = ::ActiveRecord::Base.connection_handler.retrieve_connection_pool(connection_name, shard: shard)
      if pool
        setup_shared_connection_pool

        unless @fixture_connection_pools.include?(pool)
          pool.pin_connection!(lock_threads)
          pool.lease_connection
          @fixture_connection_pools << pool
        end
      end
    end
  end
end