72 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Ruby
		
	
	
	
			
		
		
	
	
			72 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Ruby
		
	
	
	
# frozen_string_literal: true
 | 
						|
 | 
						|
require 'tempfile'
 | 
						|
 | 
						|
module Gitlab
 | 
						|
  module Composer
 | 
						|
    class Cache
 | 
						|
      def initialize(project:, name:, last_page_sha: nil)
 | 
						|
        @project = project
 | 
						|
        @name = name
 | 
						|
        @last_page_sha = last_page_sha
 | 
						|
      end
 | 
						|
 | 
						|
      def execute
 | 
						|
        Packages::Composer::Metadatum.transaction do # rubocop: disable CodeReuse/ActiveRecord
 | 
						|
          # make sure we lock these records at the start
 | 
						|
          locked_package_metadata
 | 
						|
 | 
						|
          if locked_package_metadata.any?
 | 
						|
            mark_pages_for_delete(shas_to_delete)
 | 
						|
 | 
						|
            create_cache_page!
 | 
						|
 | 
						|
            # assign the newest page SHA to the packages
 | 
						|
            locked_package_metadata.update_all(version_cache_sha: version_index.sha)
 | 
						|
          elsif @last_page_sha
 | 
						|
            mark_pages_for_delete([@last_page_sha])
 | 
						|
          end
 | 
						|
        end
 | 
						|
      end
 | 
						|
 | 
						|
      private
 | 
						|
 | 
						|
      def mark_pages_for_delete(shas)
 | 
						|
        Packages::Composer::CacheFile
 | 
						|
          .with_namespace(@project.namespace)
 | 
						|
          .with_sha(shas)
 | 
						|
          .update_all(delete_at: 1.day.from_now)
 | 
						|
      end
 | 
						|
 | 
						|
      def create_cache_page!
 | 
						|
        Packages::Composer::CacheFile
 | 
						|
          .safe_find_or_create_by!(namespace_id: @project.namespace_id, file_sha256: version_index.sha) do |cache_file|
 | 
						|
            cache_file.file = CarrierWaveStringFile.new(version_index.to_json)
 | 
						|
          end
 | 
						|
      end
 | 
						|
 | 
						|
      def version_index
 | 
						|
        @version_index ||= ::Gitlab::Composer::VersionIndex.new(siblings)
 | 
						|
      end
 | 
						|
 | 
						|
      def siblings
 | 
						|
        @siblings ||= locked_package_metadata.map(&:package)
 | 
						|
      end
 | 
						|
 | 
						|
      # find all metadata of the package versions and lock it for update
 | 
						|
      def locked_package_metadata
 | 
						|
        @locked_package_metadata ||= Packages::Composer::Metadatum
 | 
						|
          .for_package(@name, @project.id)
 | 
						|
          .locked_for_update
 | 
						|
      end
 | 
						|
 | 
						|
      def shas_to_delete
 | 
						|
        locked_package_metadata
 | 
						|
          .map(&:version_cache_sha)
 | 
						|
          .reject { |sha| sha == version_index.sha }
 | 
						|
          .compact
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
end
 |