Class: Gitlab::Database::LoadBalancing::SessionMap

Inherits:
Object
  • Object
show all
Defined in:
lib/gitlab/database/load_balancing/session_map.rb

Constant Summary collapse

CACHE_KEY =
:gitlab_load_balancer_session_map
InvalidLoadBalancerNameError =
Class.new(StandardError)

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSessionMap

Returns a new instance of SessionMap.



38
39
40
41
42
43
44
# File 'lib/gitlab/database/load_balancing/session_map.rb', line 38

def initialize
  @session_map = Gitlab::Database.all_database_names.to_h do |k|
    [k.to_sym, Gitlab::Database::LoadBalancing::Session.new]
  end

  @session_map[:primary] = Gitlab::Database::LoadBalancing::Session.new
end

Instance Attribute Details

#session_mapObject (readonly)

Returns the value of attribute session_map.



36
37
38
# File 'lib/gitlab/database/load_balancing/session_map.rb', line 36

def session_map
  @session_map
end

Class Method Details

.clear_sessionObject



23
24
25
# File 'lib/gitlab/database/load_balancing/session_map.rb', line 23

def self.clear_session
  RequestStore.delete(CACHE_KEY)
end

.current(load_balancer) ⇒ Object

lb - Gitlab::Database::LoadBalancing::LoadBalancer instance



12
13
14
# File 'lib/gitlab/database/load_balancing/session_map.rb', line 12

def self.current(load_balancer)
  cached_instance.lookup(load_balancer)
end

.with_sessions(models) ⇒ Object

models - Array<ActiveRecord::Base>



17
18
19
20
21
# File 'lib/gitlab/database/load_balancing/session_map.rb', line 17

def self.with_sessions(models)
  dbs = models.map { |m| m.load_balancer.name }.uniq
  dbs.each { |db| cached_instance.validate_db_name(db) }
  ScopedSessions.new(dbs, cached_instance.session_map)
end

.without_sticky_writesObject



27
28
29
# File 'lib/gitlab/database/load_balancing/session_map.rb', line 27

def self.without_sticky_writes(&)
  with_sessions(Gitlab::Database::LoadBalancing.base_models).ignore_writes(&)
end

Instance Method Details

#lookup(load_balancer) ⇒ Object



46
47
48
49
50
# File 'lib/gitlab/database/load_balancing/session_map.rb', line 46

def lookup(load_balancer)
  name = load_balancer.name
  validate_db_name(name)
  session_map[name]
end

#validate_db_name(db) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/gitlab/database/load_balancing/session_map.rb', line 52

def validate_db_name(db)
  if db == :primary
    # Allow :primary in general but report the exeception. We should expect primary for:
    #
    # 1. rake task db migrations as ActiveRecord::Tasks::PostgresqlDatabaseTasks calls
    # .establish_connection using a hash which resets the name from :main/:ci to :primary.
    # See
    # https://github.com/rails/rails/blob/v7.0.8.4/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb#L97
    #
    # 2. In the case of derailed test in memory-on-boot job, the runtime is unknown.
    # 3. `scripts/regenerate-schema` which runs in RAILS_ENV=test
    Gitlab::ErrorTracking.track_exception(
      InvalidLoadBalancerNameError.new("Using #{db} load balancer in #{Gitlab::Runtime.safe_identify}.")
    )

    return
  end

  return if session_map[db]

  # All other load balancer names are invalid and should raise an error
  raise InvalidLoadBalancerNameError, "Invalid load balancer name #{db} in #{Gitlab::Runtime.safe_identify}."
end