Class: InternalId

Inherits:
ApplicationRecord show all
Extended by:
Gitlab::Utils::StrongMemoize
Defined in:
app/models/internal_id.rb

Overview

An InternalId is a strictly monotone sequence of integers generated for a given scope and usage.

The monotone sequence may be broken if an ID is explicitly provided to `#track_greatest`.

For example, issues use their project to scope internal ids: In that sense, scope is “project” and usage is “issues”. Generated internal ids for an issue are unique per project.

See InternalId#usage enum for available usages.

In order to leverage InternalId for other usages, the idea is to

  • Add `usage` value to enum

  • (Optionally) add columns to `internal_ids` if needed for scope.

Defined Under Namespace

Classes: ImplicitlyLockingInternalIdGenerator

Constant Summary

Constants inherited from ApplicationRecord

ApplicationRecord::MAX_PLUCK

Class Method Summary collapse

Methods included from Gitlab::Utils::StrongMemoize

clear_memoization, strong_memoize, strong_memoized?

Methods inherited from ApplicationRecord

cached_column_list, #create_or_load_association, declarative_enum, default_select_columns, id_in, id_not_in, iid_in, pluck_primary_key, 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 SensitiveSerializableHash

#serializable_hash

Class Method Details

.flush_records!(filter) ⇒ Object

Flushing records is generally safe in a sense that those records are going to be re-created when needed.

A filter condition has to be provided to not accidentally flush records for all projects.

Raises:

  • (ArgumentError)

50
51
52
53
54
# File 'app/models/internal_id.rb', line 50

def flush_records!(filter)
  raise ArgumentError, "filter cannot be empty" if filter.blank?

  where(filter).delete_all
end

.generate_next(subject, scope, usage, init) ⇒ Object


37
38
39
# File 'app/models/internal_id.rb', line 37

def generate_next(subject, scope, usage, init)
  build_generator(subject, scope, usage, init).generate
end

.internal_id_transactions_increment(operation:, usage:) ⇒ Object


56
57
58
59
60
61
62
# File 'app/models/internal_id.rb', line 56

def internal_id_transactions_increment(operation:, usage:)
  self.internal_id_transactions_total.increment(
    operation: operation,
    usage: usage.to_s,
    in_transaction: InternalId.connection.transaction_open?.to_s
  )
end

.internal_id_transactions_totalObject


64
65
66
67
68
69
70
71
# File 'app/models/internal_id.rb', line 64

def internal_id_transactions_total
  strong_memoize(:internal_id_transactions_total) do
    name = :gitlab_internal_id_transactions_total
    comment = 'Counts all the internal ids happening within transaction'

    Gitlab::Metrics.counter(name, comment)
  end
end

.reset(subject, scope, usage, value) ⇒ Object


41
42
43
# File 'app/models/internal_id.rb', line 41

def reset(subject, scope, usage, value)
  build_generator(subject, scope, usage).reset(value)
end

.track_greatest(subject, scope, usage, new_value, init) ⇒ Object


33
34
35
# File 'app/models/internal_id.rb', line 33

def track_greatest(subject, scope, usage, new_value, init)
  build_generator(subject, scope, usage, init).track_greatest(new_value)
end