Repository: rails/rails
File: activestorage/lib/active_storage/service/gcs_service.rb (Ruby)

Code before:
        bucket.file(key, skip_lookup: skip_lookup)
      end

      # Reads the file for the given key in chunks, yielding each to the block.
      def stream(key)
        file = file_for(key, skip_lookup: false)

        chunk_size = 5.megabytes
        offset = 0

        raise ActiveStorage::FileNotFoundError unless file.present?

        while offset < file.size
          yield file.download(range: offset..(offset + chunk_size - 1)).string
          offset += chunk_size
        end
      end

      def bucket
        @bucket ||= client.bucket(config.fetch(:bucket), skip_lookup: true)
      end

      def client
        @client ||= Google::Cloud::Storage.new(**config.except(:bucket, :cache_control, :iam, :gsa_email))
      end

      def issuer
        @issuer ||= @config[:gsa_email].presence || email_from_metadata_server
      end

      def email_from_metadata_server
        env = Google::Cloud.env
        raise MetadataServerNotFoundError if !env.metadata?

        email = env.lookup_metadata("instance", "service-accounts/default/email")
        email.presence or raise MetadataServerError
      end

      def signer
        # https://googleapis.dev/ruby/google-cloud-storage/latest/Google/Cloud/Storage/Project.html#signed_url-instance_method
        lambda do |string_to_sign|
          iam_client = Google::Apis::IamcredentialsV1::IAMCredentialsService.new

          # We explicitly do not set iam_client.authorization so that it uses the
          # credentials set by the application at Google::Apis::RequestOptions.default.authorization.
          # If the application does not set it, the GCP libraries will automatically
          # determine it on each call. This code previously explicitly set the
          # authorization to Google::Auth.get_application_default which triggers
          # an explicit call to the metadata server - given this lambda is called
          # for a significant number of file operations, it can lead to considerable
          # tail latencies and even metadata server overloads. Additionally, that

Review comment (suggestion):
I think these methods should have been just moved to be public

because when defined in the `def initialize` method, they can potentially perform a network call at initialization ( to retrieve bucket metadata or idk), instead of when they're actually used 

Code after:


      attr_reader :config

      def file_for(key, skip_lookup: true)
        bucket.file(key, skip_lookup: skip_lookup)
      end

      # Reads the file for the given key in chunks, yielding each to the block.
      def stream(key)
        file = file_for(key, skip_lookup: false)

        chunk_size = 5.megabytes
        offset = 0

        raise ActiveStorage::FileNotFoundError unless file.present?

        while offset < file.size
          yield file.download(range: offset..(offset + chunk_size - 1)).string
          offset += chunk_size
        end
      end

      def issuer
        @issuer ||= @config[:gsa_email].presence || email_from_metadata_server
      end

      def email_from_metadata_server
        env = Google::Cloud.env
        raise MetadataServerNotFoundError if !env.metadata?

        email = env.lookup_metadata("instance", "service-accounts/default/email")
        email.presence or raise MetadataServerError
      end

      def signer
        # https://googleapis.dev/ruby/google-cloud-storage/latest/Google/Cloud/Storage/Project.html#signed_url-instance_method
        lambda do |string_to_sign|
          iam_client = Google::Apis::IamcredentialsV1::IAMCredentialsService.new

          # We explicitly do not set iam_client.authorization so that it uses the
          # credentials set by the application at Google::Apis::RequestOptions.default.authorization.
          # If the application does not set it, the GCP libraries will automatically
          # determine it on each call. This code previously explicitly set the
          # authorization to Google::Auth.get_application_default which triggers
          # an explicit call to the metadata server - given this lambda is called
          # for a significant number of file operations, it can lead to considerable
          # tail latencies and even metadata server overloads. Additionally, that
          # prevented applications from being able to configure the credentials
          # used to perform the signature operation.