Class: DesignManagement::Version
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- DesignManagement::Version
- Extended by:
- Gitlab::ExclusiveLeaseHelpers
- Includes:
- AfterCommitQueue, Gitlab::Utils::StrongMemoize, Importable, ShaAttribute
- Defined in:
- app/models/design_management/version.rb
Defined Under Namespace
Classes: CouldNotCreateVersion
Constant Summary collapse
- NotSameIssue =
Class.new(StandardError)
- CREATION_TTL =
5.seconds
- RETRY_DELAY =
->(num) { 0.2.seconds * num**2 }
Constants included from Gitlab::ExclusiveLeaseHelpers
Gitlab::ExclusiveLeaseHelpers::FailedToObtainLockError
Constants inherited from ApplicationRecord
Constants included from ResetOnUnionError
ResetOnUnionError::MAX_RESET_PERIOD
Instance Attribute Summary
Attributes included from Importable
Class Method Summary collapse
-
.create_for_designs(design_actions, sha, author) ⇒ Object
This is the one true way to create a Version.
- .with_lock(project_id, repository, &block) ⇒ Object
Instance Method Summary collapse
Methods included from Gitlab::ExclusiveLeaseHelpers
Methods included from AfterCommitQueue
#run_after_commit, #run_after_commit_or_now
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
Class Method Details
.create_for_designs(design_actions, sha, author) ⇒ Object
This is the one true way to create a Version.
This method means you can avoid the paradox of versions being invalid without designs, and not being able to add designs without a saved version. Also this method inserts designs in bulk, rather than one by one.
Before calling this method, callers must guard against concurrent modification by obtaining the lock on the design repository. See: ‘DesignManagement::Version.with_lock`.
Parameters:
-
design_actions [DesignManagement::DesignAction]:
the actions that have been performed in the repository.
-
sha [String]:
the SHA of the commit that performed them
-
author [User]:
the user who performed the commit
returns [DesignManagement::Version]
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'app/models/design_management/version.rb', line 81 def self.create_for_designs(design_actions, sha, ) issue_id, not_uniq = design_actions.map(&:issue_id).compact.uniq raise NotSameIssue, 'All designs must belong to the same issue!' if not_uniq transaction do version = new(sha: sha, issue_id: issue_id, author: ) version.save(validate: false) # We need it to have an ID. Validate later when designs are present rows = design_actions.map { |action| action.row_attrs(version) } ApplicationRecord.legacy_bulk_insert(::DesignManagement::Action.table_name, rows) # rubocop:disable Gitlab/BulkInsert version.designs.reset version.validate! design_actions.each(&:performed) version end rescue StandardError raise CouldNotCreateVersion.new(sha, issue_id, design_actions) end |
.with_lock(project_id, repository, &block) ⇒ Object
105 106 107 108 109 110 111 112 |
# File 'app/models/design_management/version.rb', line 105 def self.with_lock(project_id, repository, &block) key = "with_lock:#{name}:{#{project_id}}" in_lock(key, ttl: CREATION_TTL, retries: 5, sleep_sec: RETRY_DELAY) do |_retried| repository.create_if_not_exists yield end end |
Instance Method Details
#author ⇒ Object
121 122 123 |
# File 'app/models/design_management/version.rb', line 121 def super || ( if persisted?) end |
#designs_by_event ⇒ Object
114 115 116 117 118 119 |
# File 'app/models/design_management/version.rb', line 114 def designs_by_event actions .includes(:design) .group_by(&:event) .transform_values { |group| group.map(&:design) } end |
#diff_refs ⇒ Object
125 126 127 |
# File 'app/models/design_management/version.rb', line 125 def diff_refs strong_memoize(:diff_refs) { commit&.diff_refs } end |
#reset ⇒ Object
129 130 131 132 |
# File 'app/models/design_management/version.rb', line 129 def reset %i[diff_refs commit].each { |k| clear_memoization(k) } super end |