【问题标题】:How to run a background task in Sinatra to avoid Heroku 30 second timout如何在 Sinatra 中运行后台任务以避免 Heroku 30 秒超时
【发布时间】:2020-03-16 20:54:39
【问题描述】:

我正在构建一个 Sinatra 应用程序来使用 Ghostscript 处理 PDF,但是当我将它推送到 Heroku 时,它会超时,因为 Ghostscript 处理 PDF 的时间超过 30 秒。

我需要一种方法来在后台运行 Ghostscript 命令并显示加载指示器直到它完成,否则我需要不断地 ping 服务器直到处理完成。我搜索了几个星期如何完成此操作,但没有任何效果。

这是我的 POST 操作:

post '/process_pdf' do
    unless params[:file] && params[:file][:tempfile] && params[:file][:filename]
      return erb :form
    end

    @filename = params[:file][:filename].gsub!(/[^0-9A-Za-z.]/, '')
    @output_file_name = "#{Time.now.strftime('%b_%d_%I_%M')}_#{@filename}"
    @file = params[:file][:tempfile]

    File.open("#{settings.root}/tmp/#{@filename}", 'wb') do |file|
      file.write(@file.read)
      file.close
    end

    # @pdf = GS.run("#{settings.root}/tmp/#{@filename}") do |command|
    #   command.option(GS::PDFA)
    #   command.option(GS::BATCH)
    #   command.option(GS::NO_PAUSE)
    #   command.option(GS::PROCESS_COLOR_MODEL, 'DeviceCMYK')
    #   command.option(GS::DEVICE, 'pdfwrite')
    #   command.option(GS::PDFA_COMPATIBILITY_POLICY, '1')
    #   command.option('CompatibilityLevel', '1.4')
    #   command.option('PDFSETTINGS', 'prepress')
    #   command.option(GS::OUTPUT_FILE,
    #                  "#{settings.root}/tmp/#{@output_file_name}")
    # end

    # until @pdf.success?
    #   puts 'loading...'
    #   sleep 1
    # end

    Kernel.system 'gs -dPDFA -dBATCH -dNOPAUSE'\
                  ' -sProcessColorModel=DeviceCMYK'\
                  ' -sDEVICE=pdfwrite -sPDFACompatibilityPolicy=1'\
                  ' -dCompatibilityLevel=1.4 -dPDFSETTINGS=/prepress'\
                  " -sOutputFile=#{settings.root}/tmp/#{@output_file_name}"\
                  " #{settings.root}/tmp/#{@filename}"

    erb :process_pdf
  end

并在处理完成后显示:

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    <link rel="stylesheet" type="text/css" href="<%= url("/style.css")%>">
    <title>Processing PDF</title>
  </head>
  <body>
    <%= send_file "#{settings.root}/tmp/#{@output_file_name}" %>

    <script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
  </body>
</html>

在我的 POST 操作中,我尝试了多种使用 Ghostscript 处理 PDF 的方法,但在 Heroku 上的 30 秒超时内没有任何方法可以加快它的速度。我什至尝试检查 Process::Statussuccess?(这是 gs-ruby gem 提供的),但是当它甚至到达那个块时,它已经处理并且已经太晚了。

这在本地运行良好,直到它在 Heroku 上才失败,因为处理时间太长。

【问题讨论】:

  • 能否提供超时错误。超时可以指很多事情。比如处理时间太长,网页没有及时回复,...
  • 嘿@TinNguyen,感谢您的回复! papertrail 上的错误代码是at=error code=H12 desc="Request timeout" method=POST path="/process_pdf" status=503
  • devcenter.heroku.com/articles/request-timeout "超时值不可配置。如果您的服务器需要超过 30 秒才能完成给定的请求,我们建议将该工作转移到后台任务或工作人员以定期 ping 您的服务器到看看处理请求是否已经完成。这种模式可以让您的 Web 进程腾出时间来做更多的工作,并减少整体应用程序响应时间。您的 PDF 处理是一个阻塞调用,因为在完成之前没有计算任何其他内容。您需要创建后台任务或单独的工作人员。
  • 我知道,这就是我问这个问题的原因。使用 sinatra,添加后台任务并不像在 rails 上安装 sidekiq gem 那样容易。我还没有找到在 sinatra 中创建后台任务的好解决方案,我希望有人能推荐一下
  • 虽然 Sinatra 是一个出色的服务器环境,但它的功能也不如其他环境那样全面,因此它可能无法满足您的需求。 Padrino 是我的经验的下一步,然后你进入 Rails。

标签: ruby heroku sinatra


【解决方案1】:

我建议您使用 DelayedJob (https://github.com/collectiveidea/delayed_job)。根据您的架构,它是您可以设置的最简单的后台作业处理器,它只需要一个数据库来存储和处理作业。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-09
    • 2021-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多