H12 Request timeout 503 on heroku then 200 success

时间:2017-10-23 20:47:43

标签: ruby heroku sinatra

I am running a small docker image that starts a ruby Sinatra API. Th point of the API is to receive an image, preprocess it using a script then use Tesseract OCR to return the text from the image.

The issue I'm having is that I'm getting a 503 error then a 300 success with the text, but it's of no use as my ios app has already received the 503 error and continued on its way.

require 'sinatra'
require "json"
require 'sinatra/base'
require 'sinatra'
require 'json'
require 'fileutils'
require 'tempfile'
require "base64"
require 'puma_worker_killer'

PumaWorkerKiller.enable_rolling_restart

set :protection, except: [ :json_csrf ]
port = ENV['PORT'] || 8080
set :port, port
set :bind, '0.0.0.0'

post '/extractText' do
  begin
    bas64Image = Base64.decode64(params[:image])
    imageFile = Tempfile.new(['image', '.png'])
    imageFile.write(bas64Image)
    imageFile.close
    `textcleaner #{imageFile.path} #{imageFile.path}`
    # `textdeskew #{imageFile.path} #{imageFile.path}`
    output = `tesseract #{imageFile.path} --psm 6 --oem 2 stdout`
    p output
  rescue
    status 402
    return "Error reading image"
  end
  status 200
  return output
end

Heres the heroku read out i get:

2017-10-23T20:22:00.548029+00:00 heroku[router]: at=error code=H12 desc="Request timeout" method=POST path="/extractText" host=tesseractimageserver.herokuapp.com request_id=7b179829-ef1f-4e18-844b-42b90a5c5c69 fwd="82.32.79.208" dyno=web.1 connect=1ms service=30945ms status=503 bytes=0 protocol=https
2017-10-23T20:22:42.864098+00:00 app[web.1]: "Returned text from reading image using tesseract"
2017-10-23T20:22:42.872633+00:00 app[web.1]: 82.32.79.208 - - [23/Oct/2017:20:22:42 +0000] "POST /extractText HTTP/1.1" 200 467 72.2921

Id there a way around this?

1 个答案:

答案 0 :(得分:2)

以下是它的工作原理。 Heroku对任何Web请求都有30秒超时。当新请求被路由到您的应用程序dyno并且在这30秒时间限制内没有响应时,Heroku正在丢弃连接并报告H12错误。但你的dyno仍在处理网络请求,甚至没有人会使用它的响应。客户已经走了。由于这种行为,建议对长时间运行的操作设置某种超时机制。如果您向此类端点发送了许多请求,则可以轻松地停止整个应用程序。

解决此问题的方法是在后台作业中处理图像。因此,第一个请求将注册一个新作业并返回其ID或某种标识符。然后您的ios应用程序可以使用此ID定期ping服务器以检查作业是否已完成。