Files
danbooru/app/logical/storage_manager.rb
evazion e7744cb6e3 uploads: generate thumbnails in parallel.
Make uploads faster by generating and saving thumbnails in parallel.

We generate each thumbnail in parallel, then send each thumbnail to the
backend image servers in parallel.

Most images have 5 variants: 'preview' (150x150), 180x180, 360x360,
720x720, and 'sample' (850px width). Plus the original file, that's 6
files we have to save. In production we have 2 image servers, so we have
to save each file twice, to 2 remote servers. Doing all this in parallel
should make uploads significantly faster.
2022-02-04 16:20:50 -06:00

61 lines
2.0 KiB
Ruby

# frozen_string_literal: true
# StorageManager is an abstract superclass that defines a simple interface for
# storing files on local or remote backends. All image files stored by Danbooru
# are handled by a StorageManager.
#
# A StorageManager has methods for saving, deleting, and opening files, and for
# generating URLs for files.
#
# @abstract
# @see StorageManager::Local
# @see StorageManager::Mirror
# @see StorageManager::Rclone
class StorageManager
class Error < StandardError; end
attr_reader :base_url
# Initialize a storage manager object.
#
# @param base_url [String, nil] the base URL where files are served from (ex:
# "https://cdn.donmai.us"), or nil if the files don't have an URL (they're
# stored in a publicly inaccessible location).
def initialize(base_url: nil)
@base_url = base_url
end
# Store the given file at the given path. If a file already exists at that
# location it should be overwritten atomically. Either the file is fully
# written, or an error is raised and the original file is left unchanged. The
# file should never be in a partially written state.
#
# @param src_file [File] the file to store
# @param path [String] the remote path where the file should be stored
def store(io, path)
raise NotImplementedError, "store not implemented"
end
# Delete the file at the given path. If the file doesn't exist, no error
# should be raised.
# @param path [String] the remote path of the file to be deleted
def delete(path)
raise NotImplementedError, "delete not implemented"
end
# Return a readonly copy of the file located at the given path.
# @param path [String] the remote path of the file to open
# @return [File] the file
def open(path)
raise NotImplementedError, "open not implemented"
end
# Return the full URL of the file at the given path, or nil if the file
# doesn't have an URL.
# @return [String, nil] the file URL
def file_url(path)
return nil if base_dir.nil?
File.join(base_url, path)
end
end