adjust preview cache
This commit is contained in:
@@ -5,6 +5,10 @@ class PreviewDocumentPageController < ActionController::API
|
||||
|
||||
FORMAT = Templates::ProcessDocument::FORMAT
|
||||
|
||||
TMPFILE_PREFIX = 'attachment-'
|
||||
TMPFILE_TTL = 5.minutes
|
||||
TMPFILE_MAX_TOTAL_SIZE = Docuseal.multitenant? ? 400.megabytes : 1.gigabyte
|
||||
|
||||
def show
|
||||
result_data =
|
||||
ApplicationRecord.signed_id_verifier.verified(params[:signed_key], purpose: :attachment)
|
||||
@@ -30,34 +34,63 @@ class PreviewDocumentPageController < ActionController::API
|
||||
allow_other_host: true
|
||||
end
|
||||
|
||||
file_path =
|
||||
if attachment.service.name == :disk
|
||||
ActiveStorage::Blob.service.path_for(attachment.key)
|
||||
else
|
||||
find_or_create_document_tempfile_path(attachment)
|
||||
end
|
||||
|
||||
preview_image =
|
||||
Templates::ProcessDocument.generate_pdf_preview_from_file(attachment, file_path, params[:id].to_i)
|
||||
open_attachment_io(attachment) do |io|
|
||||
Templates::ProcessDocument.generate_pdf_preview_from_io(attachment, io, params[:id].to_i)
|
||||
end
|
||||
|
||||
redirect_to preview_image.url(time: ActiveStorage::Attachment.service_url_time), allow_other_host: true
|
||||
end
|
||||
|
||||
def find_or_create_document_tempfile_path(attachment)
|
||||
file_path = "#{Dir.tmpdir}/attachment-#{Digest::SHA1.hexdigest("#{attachment.id}-#{attachment.uuid}")}"
|
||||
def open_attachment_io(attachment, &)
|
||||
return File.open(ActiveStorage::Blob.service.path_for(attachment.key), 'rb', &) if attachment.service.name == :disk
|
||||
|
||||
File.open(file_path, File::RDWR | File::CREAT, 0o644) do |f|
|
||||
f.flock(File::LOCK_EX)
|
||||
file_name = "#{TMPFILE_PREFIX}#{Digest::SHA1.hexdigest("#{attachment.id}-#{attachment.uuid}")}"
|
||||
|
||||
file_path = File.join(Dir.tmpdir, file_name)
|
||||
|
||||
File.open(file_path, File::RDWR | File::CREAT, 0o644) do |file|
|
||||
file.flock(File::LOCK_EX)
|
||||
|
||||
# rubocop:disable Style/ZeroLengthPredicate
|
||||
if f.size.zero?
|
||||
f.binmode
|
||||
if file.size.zero?
|
||||
cleanup_stale_tempfiles
|
||||
|
||||
f.write(attachment.download)
|
||||
file.binmode
|
||||
|
||||
file.write(attachment.download)
|
||||
else
|
||||
FileUtils.touch(file_path)
|
||||
end
|
||||
# rubocop:enable Style/ZeroLengthPredicate
|
||||
end
|
||||
|
||||
file_path
|
||||
file.flock(File::LOCK_UN)
|
||||
|
||||
yield file
|
||||
end
|
||||
end
|
||||
|
||||
def cleanup_stale_tempfiles
|
||||
entries =
|
||||
Dir.glob(File.join(Dir.tmpdir, "#{TMPFILE_PREFIX}*")).filter_map do |path|
|
||||
stat = File.stat(path)
|
||||
|
||||
[path, stat.mtime, stat.size]
|
||||
rescue Errno::ENOENT
|
||||
nil
|
||||
end
|
||||
|
||||
total_size = entries.sum(&:last)
|
||||
stale_time = TMPFILE_TTL.ago
|
||||
|
||||
entries.sort_by(&:second).each do |path, mtime, size|
|
||||
break if mtime > stale_time && total_size <= TMPFILE_MAX_TOTAL_SIZE
|
||||
|
||||
File.unlink(path)
|
||||
|
||||
total_size -= size
|
||||
rescue Errno::ENOENT
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user