Class: Namespaces::Descendants

Inherits:
ApplicationRecord show all
Defined in:
app/models/namespaces/descendants.rb

Constant Summary

Constants inherited from ApplicationRecord

ApplicationRecord::MAX_PLUCK

Constants included from HasCheckConstraints

HasCheckConstraints::NOT_NULL_CHECK_PATTERN

Constants included from ResetOnColumnErrors

ResetOnColumnErrors::MAX_RESET_PERIOD

Class Method Summary collapse

Methods inherited from ApplicationRecord

===, cached_column_list, #create_or_load_association, current_transaction, declarative_enum, default_select_columns, delete_all_returning, #deleted_from_database?, id_in, id_not_in, iid_in, nullable_column?, primary_key_in, #readable_by?, safe_ensure_unique, safe_find_or_create_by, safe_find_or_create_by!, #to_ability_name, underscore, where_exists, where_not_exists, with_fast_read_statement_timeout, without_order

Methods included from Organizations::Sharding

#sharding_organization

Methods included from ResetOnColumnErrors

#reset_on_union_error, #reset_on_unknown_attribute_error

Methods included from Gitlab::SensitiveSerializableHash

#serializable_hash

Class Method Details

.expire_for(namespace_ids) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'app/models/namespaces/descendants.rb', line 11

def self.expire_for(namespace_ids)
  # Union:
  # - Look up all parent ids including the given ids via traversal_ids
  # - Include the given ids to handle the case when the namespaces records are already deleted
  sql = <<~SQL
  WITH namespace_ids AS MATERIALIZED (
    (
      SELECT ids.id
      FROM namespaces, UNNEST(traversal_ids) ids(id)
      WHERE namespaces.id IN (?)
    ) UNION
    (SELECT UNNEST(ARRAY[?]) AS id)
  )
  UPDATE namespace_descendants SET outdated_at = ? FROM namespace_ids WHERE namespace_descendants.namespace_id = namespace_ids.id
  SQL

  connection.execute(sanitize_sql_array([sql, namespace_ids, namespace_ids, Time.current]))
end

.expire_recursive_for(group) ⇒ Object



30
31
32
33
34
35
36
# File 'app/models/namespaces/descendants.rb', line 30

def self.expire_recursive_for(group)
  # Expire `group` and all ancestors
  expire_for([group.id])

  # Expire all subgroups
  Namespaces::Descendants.where(namespace_id: group.self_and_descendant_ids).update_all(outdated_at: Time.current)
end

.load_outdated_batch(batch_size) ⇒ Object



38
39
40
41
42
43
44
# File 'app/models/namespaces/descendants.rb', line 38

def self.load_outdated_batch(batch_size)
  where
    .not(outdated_at: nil)
    .limit(batch_size)
    .lock('FOR UPDATE SKIP LOCKED')
    .pluck_primary_key
end

.upsert_with_consistent_data(namespace:, self_and_descendant_ids:, self_and_descendant_group_ids:, all_project_ids:, all_unarchived_project_ids:, outdated_at: nil) ⇒ Object



46
47
48
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 'app/models/namespaces/descendants.rb', line 46

def self.upsert_with_consistent_data(
  namespace:, self_and_descendant_ids:, self_and_descendant_group_ids:,
  all_project_ids:, all_unarchived_project_ids:, outdated_at: nil)
  query = <<~SQL
    INSERT INTO namespace_descendants
    (namespace_id, traversal_ids, self_and_descendant_ids, self_and_descendant_group_ids,
     all_project_ids, all_unarchived_project_ids, outdated_at, calculated_at)
    VALUES
    (
      ?,
      ARRAY[?]::bigint[],
      ARRAY_REMOVE(ARRAY[?]::bigint[], NULL),
      ARRAY_REMOVE(ARRAY[?]::bigint[], NULL),
      ARRAY_REMOVE(ARRAY[?]::bigint[], NULL),
      ARRAY_REMOVE(ARRAY[?]::bigint[], NULL),
      NULL,
      ?
    )
    ON CONFLICT(namespace_id)
    DO UPDATE SET
      traversal_ids = EXCLUDED.traversal_ids,
      self_and_descendant_ids = EXCLUDED.self_and_descendant_ids,
      self_and_descendant_group_ids = EXCLUDED.self_and_descendant_group_ids,
      all_project_ids = EXCLUDED.all_project_ids,
      all_unarchived_project_ids = EXCLUDED.all_unarchived_project_ids,
      #{handle_outdated_at(outdated_at)}
      calculated_at = EXCLUDED.calculated_at
  SQL

  connection.execute(sanitize_sql_array([
    query,
    namespace.id,
    namespace.traversal_ids,
    self_and_descendant_ids,
    self_and_descendant_group_ids,
    all_project_ids,
    all_unarchived_project_ids,
    Time.current
  ]))
end