Class: DesignManagement::Version
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- DesignManagement::Version
- Extended by:
- Gitlab::ExclusiveLeaseHelpers
- 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
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 Gitlab::Utils::StrongMemoize
#clear_memoization, #strong_memoize, #strong_memoized?
Methods included from AfterCommitQueue
#run_after_commit, #run_after_commit_or_now
Methods inherited from ApplicationRecord
at_most, id_in, id_not_in, iid_in, pluck_primary_key, primary_key_in, safe_ensure_unique, safe_find_or_create_by, safe_find_or_create_by!, underscore, where_exists, with_fast_statement_timeout, without_order
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]
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'app/models/design_management/version.rb', line 78 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) } Gitlab::Database.bulk_insert(::DesignManagement::Action.table_name, rows) # rubocop:disable Gitlab/BulkInsert version.designs.reset version.validate! design_actions.each(&:performed) version end rescue raise CouldNotCreateVersion.new(sha, issue_id, design_actions) end |
.with_lock(project_id, repository, &block) ⇒ Object
102 103 104 105 106 107 108 109 |
# File 'app/models/design_management/version.rb', line 102 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
118 119 120 |
# File 'app/models/design_management/version.rb', line 118 def super || ( if persisted?) end |
#designs_by_event ⇒ Object
111 112 113 114 115 116 |
# File 'app/models/design_management/version.rb', line 111 def designs_by_event actions .includes(:design) .group_by(&:event) .transform_values { |group| group.map(&:design) } end |
#diff_refs ⇒ Object
122 123 124 |
# File 'app/models/design_management/version.rb', line 122 def diff_refs strong_memoize(:diff_refs) { commit&.diff_refs } end |
#reset ⇒ Object
126 127 128 129 |
# File 'app/models/design_management/version.rb', line 126 def reset %i[diff_refs commit].each { |k| clear_memoization(k) } super end |