【问题标题】:Ruby on Rails - Faraday retry request if specific response?Ruby on Rails - 如果特定响应,法拉第重试请求?
【发布时间】:2017-10-19 10:22:09
【问题描述】:

我一直在努力使用 Faraday 和我的 Ruby on Rails 应用程序。 Rails 中的 API 控制器创建一个 Model 实例,并将此数据以 JSON 序列化后发送到外部应用程序,该应用程序将处理数据并在请求后的几秒钟内在其响应中发送带有 float 编号的响应。

但是,我的应用有时会发送 50 个单独的请求,而外部应用可能会返回 502 错误字符串作为响应(请注意不是实际的 502 HTTP 错误!!!)。我尝试限制我的法拉第呼叫,但这使外部应用程序发疯,所以现在我试图弄清楚如果响应抛出这个502 字符串,如何重新提交请求。我还没有想出如何为此编写中间件,但目前还没有必要。

如果我的方法在其主体内收到特定响应,我是否可以告诉我的方法将请求重新提交给外部应用程序?

这是我的代码(每个请求都会触发此方法):

控制器

  def create
    cl = Model.where(
      attr1_id: params[:attr1_id],
      attr2_id: params[:attr2_id]
    ).first_or_initialize(params)
    cl.update(params)

    # Send new Model data (in JSON) in a request to external app
    cl_r = cl[:attr1_id]
    r = Some_model.find_by(id: cl_r)
    request = { :cl => cl, :r => r }

    # Send the request
    response = @conn.post do |req|
      req.url '/ml'
      req.headers['Content-Type'] = 'application/json'
      req.headers['password'] = 'password'
      req.body = request.to_json
    end

    # Get the response
    response_json = response.body
    response_json = response_json.gsub(/\s+/m, ' ').strip.split(" ")[1]

    # If the response (which takes a few seconds) returns a float inside its response body
    cl.update_attributes(response_attribute: response_json)
    # Else
    # Send the request that returned a 502 string inside the body to the external app again
    # End

    respond_with cl
  end

谢谢,非常感谢您的帮助!

【问题讨论】:

  • 您是否尝试过检查文档以进行重试? rubydoc.info/github/lostisland/faraday/Faraday/Request/Retry
  • @Maru ,我的请求没有失败,因此为什么不会触发重试。响应的正文中有 502,但 HTTP 标头中没有
  • 当你得到 502 时,为什么不强制它失败呢?当您收到 502 时引发自定义异常。您可以触发自定义异常的重试
  • @Maru 文档几乎不存在,我将如何使用我在此线程上提供的代码来实现这一点?

标签: ruby-on-rails api faraday


【解决方案1】:

你可以试试下面的代码

Faraday.new(your @conn params here if any) do |conn|
  conn.request :retry, max: 2, interval: 0.05,
                       interval_randomness: 0.5, backoff_factor: 2,
                       exceptions: [CustomException, 'Timeout::Error']

  response = conn.post do |req|
      req.url '/ml'
      req.headers['Content-Type'] = 'application/json'
      req.headers['password'] = 'password'
      req.body = request.to_json
    end

  raise CustomException if response.status == 502


  ...
end

您可以查看documentation 了解更多信息。

【讨论】:

  • 如何测试这个?假设我有一个使用 Faraday 的通用 HTTP 客户端,有推荐的方法来测试这种功能吗?
【解决方案2】:

你可以添加

builder.response :raise_error

如果请求不成功(基于响应代码,例如 4xx/5xx 代码),请让您的连接构建器自动让 Faraday 提升 ClientError

您还必须将 Faraday::Error 添加到 retry 配置中的异常数组中

【讨论】:

    猜你喜欢
    • 2011-04-30
    • 1970-01-01
    • 1970-01-01
    • 2022-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多