我有一个Rails应用程序,试图将大型PDF的创建传递给后台进程,并让用户在完成时可以看到它。这是一个多页文档,结合了Combine_pdf gem,并传递给delay_job。
我有3个操作:第一个创建并保存文件,第二个通过异步请求以短暂的延迟重复调用,以检查文件是否存在,第三个显示浏览器中的PDF。
第二部分很麻烦,因为它使用了File.exist?('my_file.pdf')
,但这在文件完成保存之前返回了true
。然后显示用于查看PDF的链接将导致错误(ActionController :: MissingFile)。该文件实际上在大约10秒钟后可用,此时链接可以正常工作。
我猜该文件在检查时仍在写入?如何检查文件保存已完成并且文件实际上可供读取?
答案 0 :(得分:1)
您可以写入临时文件,然后在完成后对其重命名。到目前为止,您还没有包含代码,但是类似的事情可能对您有用:
def write_and_replace(path, file, file_name, data)
file_path = File.join(folder_path, "#{file_name}.pdf")
temp_file_path = File.join(folder_path, "temp_#{file_name}.pdf")
File.open(temp_file_path, 'w') { |f| f.write(data) }
# Args: existing file, new name
File.rename(path, file_path)
File.rename(temp_file_path, file)
File.delete(file_path)
end
答案 1 :(得分:1)
这是(非常广泛且大致而言)我的操作方式:
首先,我在正在调用后台创建过程的控制器上调用post
操作。该操作将创建一个具有相关ServiceRequest
和状态service_request.details
的{{1}}(我的应用程序中的模型)。然后created
被发送到后台进程(我使用RabbitMQ)。然后该操作返回service_request
。
前端开始(通过AJAX)对服务请求端点进行ping操作(类似service_request.id
),然后service_requests/:id
的{{1}}操作会发回ServiceRequestController
(以及其他内容,包括show
。这会在service_request.status
既不是service_request.results
也不是service_request.status
时循环。
同时,后台进程将创建PDF。完成后,它将completed
设置为failed
。并且,它设置service_request.status
包含前端定位和检索PDF所需的数据。 (因为我在Heroku上,所以我将PDF存储到AWS存储桶中)。
当前端最终收到service_request.status completed
时,它将使用service_request.results
来获取并显示PDF。