Class: Gitlab::Database::LoadBalancing::Session

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

Overview

Tracking of load balancing state per user session.

A session starts at the beginning of a request and ends once the request has been completed. Sessions can be used to keep track of what hosts should be used for queries.

Instance Method Summary collapse

Constructor Details

#initializeSession

Returns a new instance of Session.



12
13
14
15
16
17
18
# File 'lib/gitlab/database/load_balancing/session.rb', line 12

def initialize
  @use_primary = false
  @performed_write = false
  @ignore_writes = false
  @fallback_to_replicas_for_ambiguous_queries = false
  @use_replicas_for_read_queries = false
end

Instance Method Details

#fallback_to_replicas_for_ambiguous_queriesObject

Indicate that the ambiguous SQL statements from anywhere inside this block should use a replica. The ambiguous statements include:

  • Transactions.

  • Custom queries (via exec_query, execute, etc.)

  • In-flight connection configuration change (SET LOCAL statement_timeout = 5000)

This is a weak enforcement. This helper incorporates well with primary stickiness:

  • If the queries are about to write

  • The current session already performed writes

  • It prefers to use primary, aka, use_primary or use_primary! were called



79
80
81
82
83
84
85
# File 'lib/gitlab/database/load_balancing/session.rb', line 79

def fallback_to_replicas_for_ambiguous_queries
  previous_flag = @fallback_to_replicas_for_ambiguous_queries
  @fallback_to_replicas_for_ambiguous_queries = true
  yield
ensure
  @fallback_to_replicas_for_ambiguous_queries = previous_flag
end

#fallback_to_replicas_for_ambiguous_queries?Boolean

Returns:

  • (Boolean)


87
88
89
# File 'lib/gitlab/database/load_balancing/session.rb', line 87

def fallback_to_replicas_for_ambiguous_queries?
  @fallback_to_replicas_for_ambiguous_queries == true && !use_primary? && !performed_write?
end

#ignore_writesObject Also known as: without_sticky_writes



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

def ignore_writes
  @ignore_writes = true

  yield
ensure
  @ignore_writes = false
end

#performed_write?Boolean

Returns:

  • (Boolean)


99
100
101
# File 'lib/gitlab/database/load_balancing/session.rb', line 99

def performed_write?
  @performed_write
end

#use_primaryObject



30
31
32
33
34
35
36
# File 'lib/gitlab/database/load_balancing/session.rb', line 30

def use_primary
  used_primary = @use_primary
  @use_primary = true
  yield
ensure
  @use_primary = used_primary || @performed_write
end

#use_primary!Object



26
27
28
# File 'lib/gitlab/database/load_balancing/session.rb', line 26

def use_primary!
  @use_primary = true
end

#use_primary?Boolean Also known as: using_primary?

Returns:

  • (Boolean)


20
21
22
# File 'lib/gitlab/database/load_balancing/session.rb', line 20

def use_primary?
  @use_primary
end

#use_replicas_for_read_queriesObject

Indicates that the read SQL statements from anywhere inside this blocks should use a replica, regardless of the current primary stickiness or whether a write query is already performed in the current session. This interface is reserved mostly for performance purpose. This is a good tool to push expensive queries, which can tolerate the replica lags, to the replicas.

Write and ambiguous queries inside this block are still handled by the primary.



56
57
58
59
60
61
62
# File 'lib/gitlab/database/load_balancing/session.rb', line 56

def use_replicas_for_read_queries
  previous_flag = @use_replicas_for_read_queries
  @use_replicas_for_read_queries = true
  yield
ensure
  @use_replicas_for_read_queries = previous_flag
end

#use_replicas_for_read_queries?Boolean

Returns:

  • (Boolean)


64
65
66
# File 'lib/gitlab/database/load_balancing/session.rb', line 64

def use_replicas_for_read_queries?
  @use_replicas_for_read_queries == true
end

#write!Object



91
92
93
94
95
96
97
# File 'lib/gitlab/database/load_balancing/session.rb', line 91

def write!
  @performed_write = true

  return if @ignore_writes

  use_primary!
end