'How can I keep temporary file even use ActiveJob Async
I have a simple upload file process and throw to background job (sidekiq) on Rails 5.2.6. I'm using ActionDispatch::Http::UploadedFile to store the file as temporary file. The temporary file will be unlink once the HTTP request is completed.
https://api.rubyonrails.org/v5.2.6/classes/ActionDispatch/Http/UploadedFile.html
Uploaded files are temporary files whose lifespan is one request. When the object is finalized Ruby unlinks the file, so there is no need to clean them with a separate maintenance task.
So I want to keep the temporary file and read it on background job as asynchronous even the HTTP request is completed in controller stage
Controller
def upload
UploadFileJob.perform_later(params[:file_uploads].path)
redirect_to root_path
end
Job
class UploadFileJob < ActiveJob::Base
def perform(file_path)
sheet = Roo::Spreadsheet.open(file_path)
end
end
The issue is when background job is running, that can't read the file because the file was removed (the HTTP request is completed).
2022-02-09T07:17:33.756Z pid=24902 tid=gqdvonm4i class=UploadFileJob jid=e8262af8c41e83f22ad06149 INFO: Adding dead ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper job e8262af8c41e83f22ad06149
2022-02-09T07:17:33.757Z pid=24902 tid=gqdvonm4i class=UploadFileJob jid=e8262af8c41e83f22ad06149 elapsed=0.009 INFO: fail
2022-02-09T07:17:33.757Z pid=24902 tid=gqdvonm4i WARN: {"context":"Job raised exception","job":{"retry":true,"queue":"default","class":"ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper","wrapped":"UploadFileJob","args":[{"job_class":"UploadFileJob","job_id":"0143f401-ddc8-4db8-9e77-32048eb7de4a","provider_job_id":null,"queue_name":"default","priority":null,"arguments":["/tmp/RackMultipart20220209-25523-ltyki7.xlsx"],"executions":0,"locale":"id"}],"jid":"e8262af8c41e83f22ad06149","created_at":1644391053.7475002,"enqueued_at":1644391053.7475615},"jobstr":"{\"retry\":true,\"queue\":\"default\",\"class\":\"ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper\",\"wrapped\":\"UploadFileJob\",\"args\":[{\"job_class\":\"UploadFileJob\",\"job_id\":\"0143f401-ddc8-4db8-9e77-32048eb7de4a\",\"provider_job_id\":null,\"queue_name\":\"default\",\"priority\":null,\"arguments\":[\"/tmp/RackMultipart20220209-25523-ltyki7.xlsx\"],\"executions\":0,\"locale\":\"id\"}],\"jid\":\"e8262af8c41e83f22ad06149\",\"created_at\":1644391053.7475002,\"enqueued_at\":1644391053.7475615}"}
2022-02-09T07:17:33.758Z pid=24902 tid=gqdvonm4i WARN: IOError: file /tmp/RackMultipart20220209-25523-ltyki7.xlsx does not exist
2022-02-09T07:17:33.758Z pid=24902 tid=gqdvonm4i WARN: /var/www/html/application/shared/bundle/ruby/2.6.0/gems/roo-2.7.1/lib/roo/base.rb:398:in `local_filename'
Is there anyway to do that only use ActionDispatch without use ActiveStorage or something else, I mean can I keep the file until the background job is done while the request is completed in controller side?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
