blob_replicator_strategy.rb 2.38 KB
Newer Older
1 2 3 4 5 6
# frozen_string_literal: true

module Geo
  module BlobReplicatorStrategy
    extend ActiveSupport::Concern

7 8 9
    include Delay
    include Gitlab::Geo::LogHelpers

10 11 12 13
    included do
      event :created
    end

14
    def handle_after_create_commit
15
      publish(:created, **created_params)
16 17 18 19

      return unless Feature.enabled?(:geo_self_service_framework)

      schedule_checksum_calculation if needs_checksum?
20 21 22
    end

    # Called by Gitlab::Geo::Replicator#consume
23
    def consume_event_created(**params)
24 25 26
      download
    end

27 28 29 30
    # Return the carrierwave uploader instance scoped to current model
    #
    # @abstract
    # @return [Carrierwave::Uploader]
31 32 33 34
    def carrierwave_uploader
      raise NotImplementedError
    end

35 36 37 38 39 40 41 42
    def calculate_checksum!
      checksum = model_record.calculate_checksum!
      update_verification_state!(checksum: checksum)
    rescue => e
      log_error('Error calculating the checksum', e)
      update_verification_state!(failure: e.message)
    end

43 44 45 46 47 48 49 50
    # Check if given checksum matches known one
    #
    # @param [String] checksum
    # @return [Boolean] whether checksum matches
    def matches_checksum?(checksum)
      model_record.verification_checksum == checksum
    end

51 52
    private

53
    # Update checksum on Geo primary database
54 55 56
    #
    # @param [String] checksum value generated by the checksum routine
    # @param [String] failure (optional) stacktrace from failed execution
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
    def update_verification_state!(checksum: nil, failure: nil)
      retry_at, retry_count = calculate_next_retry_attempt if failure.present?

      model_record.update!(
        verification_checksum: checksum,
        verified_at: Time.now,
        verification_failure: failure,
        verification_retry_at: retry_at,
        verification_retry_count: retry_count
      )
    end

    def calculate_next_retry_attempt
      retry_count = model_record.verification_retry_count.to_i + 1
      [next_retry_time(retry_count), retry_count]
    end

74 75 76 77
    def download
      ::Geo::BlobDownloadService.new(replicator: self).execute
    end

78 79 80 81
    def schedule_checksum_calculation
      Geo::BlobVerificationPrimaryWorker.perform_async(replicable_name, model_record.id)
    end

82 83 84
    def created_params
      { model_record_id: model_record.id }
    end
85 86 87 88 89 90

    def needs_checksum?
      return true unless model_record.respond_to?(:needs_checksum?)

      model_record.needs_checksum?
    end
91 92
  end
end