Class: Gitlab::Ci::Components::Usages::Aggregators::Cursor

Inherits:
Object
  • Object
show all
Includes:
Utils::StrongMemoize
Defined in:
lib/gitlab/ci/components/usages/aggregators/cursor.rb

Overview

This class represents a Redis cursor that keeps track of the data processing position and progression in Gitlab::Ci::Components::Usages::Aggregator. It updates and saves the attributes necessary for the aggregation to resume from where it was interrupted on its last run.

The cursor’s target_id is reset to 0 under these circumstances:

  1. When the Redis cursor is first initialized.

  2. When the Redis cursor expires or is lost and must be re-initialized.

  3. When the cursor advances past max_target_id.

Attributes

target_id: The target ID from which to resume aggregating the usage counts. usage_window: The window of usage data to aggregate. last_used_by_project_id: The last used_by_project_id that was counted before interruption. last_usage_count: The last usage_count that was recorded before interruption.

The last_used_by_project_id and last_usage_count only pertain to the exact target_id and usage_window that was saved before interruption. If either of the latter attributes change, then we reset the last_* values to 0.

Defined Under Namespace

Classes: Window

Constant Summary collapse

CURSOR_REDIS_KEY_TTL =
7.days

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(redis_key:, target_model:, usage_window:) ⇒ Cursor

Returns a new instance of Cursor.



40
41
42
43
44
45
46
47
# File 'lib/gitlab/ci/components/usages/aggregators/cursor.rb', line 40

def initialize(redis_key:, target_model:, usage_window:)
  @redis_key = redis_key
  @target_model = target_model
  @usage_window = usage_window
  @interrupted = false

  fetch_initial_attributes!
end

Instance Attribute Details

#interruptedObject (readonly) Also known as: interrupted?

Returns the value of attribute interrupted.



36
37
38
# File 'lib/gitlab/ci/components/usages/aggregators/cursor.rb', line 36

def interrupted
  @interrupted
end

#last_usage_countObject (readonly)

Returns the value of attribute last_usage_count.



36
37
38
# File 'lib/gitlab/ci/components/usages/aggregators/cursor.rb', line 36

def last_usage_count
  @last_usage_count
end

#last_used_by_project_idObject (readonly)

Returns the value of attribute last_used_by_project_id.



36
37
38
# File 'lib/gitlab/ci/components/usages/aggregators/cursor.rb', line 36

def last_used_by_project_id
  @last_used_by_project_id
end

#target_idObject

Returns the value of attribute target_id.



36
37
38
# File 'lib/gitlab/ci/components/usages/aggregators/cursor.rb', line 36

def target_id
  @target_id
end

#usage_windowObject (readonly)

Returns the value of attribute usage_window.



36
37
38
# File 'lib/gitlab/ci/components/usages/aggregators/cursor.rb', line 36

def usage_window
  @usage_window
end

Instance Method Details

#advanceObject



60
61
62
63
# File 'lib/gitlab/ci/components/usages/aggregators/cursor.rb', line 60

def advance
  self.target_id += 1
  self.target_id = 0 if target_id > max_target_id
end

#attributesObject



65
66
67
68
69
70
71
72
73
# File 'lib/gitlab/ci/components/usages/aggregators/cursor.rb', line 65

def attributes
  {
    target_id: target_id,
    usage_window: usage_window.to_h,
    last_used_by_project_id: last_used_by_project_id,
    last_usage_count: last_usage_count,
    max_target_id: max_target_id
  }
end

#interrupt!(last_used_by_project_id:, last_usage_count:) ⇒ Object



49
50
51
52
53
# File 'lib/gitlab/ci/components/usages/aggregators/cursor.rb', line 49

def interrupt!(last_used_by_project_id:, last_usage_count:)
  @last_used_by_project_id = last_used_by_project_id
  @last_usage_count = last_usage_count
  @interrupted = true
end

#save!Object



75
76
77
78
79
# File 'lib/gitlab/ci/components/usages/aggregators/cursor.rb', line 75

def save!
  Gitlab::Redis::SharedState.with do |redis|
    redis.set(redis_key, attributes.except(:max_target_id).to_json, ex: CURSOR_REDIS_KEY_TTL)
  end
end