【问题标题】:Configure request timeout in Phoenix?在 Phoenix 中配置请求超时?
【发布时间】:2018-03-31 22:01:04
【问题描述】:

我希望请求在一段时间后超时,比如 20 秒。如果应用程序发送响应的时间超过 20 秒,Phoenix 应该取消执行并立即回复一些错误(最好是 HTTP 503)。

我搜索了 Phoenix 文档,但找不到任何提及请求超时选项的内容。看起来 Cowboy 有一个 :timeout 选项,我尝试将其设置为 10 毫秒,但它仍然允许请求花费 8951 毫秒:

config :app, SomeApp.Endpoint,
  http: [port: 4000, timeout: 10]

事实证明,Cowboy 文档将此选项定义为:

在 Cowboy 关闭连接之前没有请求的时间(毫秒)。

这不是我想要的。

Phoenix 可以设置请求超时吗?

【问题讨论】:

    标签: elixir phoenix-framework


    【解决方案1】:

    这绝不是网络服务器/框架的责任。 Cowboy 不知道(也不应该知道!)应用程序中发生了什么,它服务于连接。 Phoenix 可以解决这个问题,但它会违反 SRP。毕竟,前面提到的超时更多是关于业务逻辑的。想象一下牛仔/凤凰将尝试处理超时:当前正在执行的处理程序会发生什么?

    也就是说,应用程序应该处理这种超时,而且它相对容易:只需将底层执行包装在任务中并设置一个你想要的超时。这样它就会灵活、可靠,您可以指定哪些控制器/动作应该以这种方式运行,哪些不应该。

    在伪代码中(这是一个真实的代码,但我没有测试它):

    def create(conn, params) do # or any other action
      fn -> prepare_result end
      |> Task.async()
      |> Task.yield(10)  # ⇐ HERE!!!
      |> case do
        {:ok, result} -> # success
          conn
          |> put_status(200)
          |> json(%{ok: result})
        nil -> # not finished yet; do smth with the task itself!
          conn
          |> put_status(503)
          |> json(%{error: :timeout})
        {:exit, reason} -> # should not happen [see Task.yield/2 docs]
          conn
          |> put_status(500) # internal server error; unexpected
          |> json(%{error: reason})
      end
    end
    

    Task.yield/2


    旁注:当然,如果您在整个应用程序中都需要这种行为,只需声明一个宏来执行此操作,或者类似。

    【讨论】:

    【解决方案2】:

    如果这样..

    config :app, SomeApp.Endpoint,
      http: [port: 4000, timeout: 10]
    

    不起作用..尝试更改为..

    config :app, SomeApp.Endpoint,
      http: [port: 4000, protocol_options: [idle_timeout: 10_000]]
    
    

    【讨论】:

    • 值得注意的是,idle_timeout 仅适用于 Cowboy 2.0+
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-13
    • 1970-01-01
    • 2011-02-26
    • 2011-12-30
    • 1970-01-01
    • 2023-03-20
    相关资源
    最近更新 更多