Я не эксперт, но мои часы поиска в Google и переполнения стека не дали мне ответа на мою проблему, поэтому я решил задать свой вопрос.
Я использую Ruby on Rails 5, с которой я работаю в Cloud9 IDE на AWS.Приложение разворачивается с использованием Heroku, который имеет 30-секундный таймаут для HTTP-запросов.Мне нужно сгенерировать PDF-файл из файла html.erb, в котором много логики и запросов, поэтому обычно для его завершения требуется около 100 секунд, и, поскольку это происходит в контроллере, он считается запросом HTTP иТребуется либо занять менее 30 секунд или завершить в фоновом режиме.Если вам известен другой способ обойти 30-секундный тайм-аут HTTP-запроса Heroku, ПОЖАЛУЙСТА, дайте мне знать.
Я спросил об этом в другом посте и получил отзыв, чтобы попытаться использовать что-то вроде Sidekiq с рельсами для обработки массивного процесса вместо попытки его с HTTP-запросом.Идея заключалась в том, чтобы поместить его в фоновый запрос и дать ему выполнить свою работу в течение полных 100 с лишним секунд, а затем каким-то образом вернуть PDF конечному пользователю (например, загрузить его автоматически).Я решил пойти на это и довел свой код до такой степени, что у меня был сервер Redis (требуется для Sidekiq), сервер Sidekiq и обычный сервер rails, работающие в унисон, чтобы позволить мне загружать и отображать PDF изSidekiq рабочий вместо контроллера.
Моя проблема в том, что метод render не доступен для рабочих!Я попытался получить к нему доступ непосредственно из источника, используя av = ActionView::Base.new()
, а затем av.render #pdf code here
, но получил следующую ошибку в моей консоли Sidekiq:
"ПРЕДУПРЕЖДЕНИЕ: NameError: неинициализированная константа PDFWorker:: ActionView "
Код в моем контроллере:
# /app/controllers/recentgrad_controller.rb
require 'sidekiq'
require "redis"
class RecentgradController < ApplicationController
def report
# things that prepare the name of the pdf, etc. go here
PDFWorker.perform_async(pdf_name, pdf_year)
redirect_to emphs_path
end
end
Код в моем работнике:
# /app/workers/pdf_worker.rb
Sidekiq.configure_client do |config|
# config.redis = { db: 1 }
config.redis = { url: 'redis://172.31.6.51:6379/0' }
end
Sidekiq.configure_server do |config|
# config.redis = { db: 1 }
config.redis = { url: 'redis://172.31.6.51:6379/0' }
end
class PDFWorker
include Sidekiq::Worker
sidekiq_options retry: false
def perform(pdf_name, pdf_year)
# create an instance of ActionView, so we can use the render method outside of a controller
av = ActionView::Base.new() # THIS is where the error comes from
av.view_paths = ActionController::Base.view_paths
av.class_eval do
include ActionController::UrlWriter
include ApplicationHelper
end
av.render pdf: "mypdf",
disposition: 'attachment',
page_height: 1300,
encoding: 'utf8',
page_size: 'A4',
footer: {html: {template: 'recent_grad/footer.html.erb'}, spacing: 0 },
margin: { top: 10, # default 10 (mm)
bottom: 20,
left: 10,
right: 10 },
template: "recent_grad/report.html.erb",
locals: {start: @start, survey: @survey, years: @years, college: @college, department: @department, program: @program, emphasis: @emphasis, questions: @questions}
end
end
Ошибка, возникающая при запуске части моегопрограмма, которая генерирует PDF:
WARN: NameError: uninitialized constant PDFWorker::ActionView