在凤凰城配置请求超时?

时间:2017-10-19 19:05:41

标签: elixir phoenix-framework

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

我已经浏览过Phoenix文档,但无法找到任何请求超时选项。看起来牛仔有一个:timeout选项,我尝试将其设置为10毫秒,但它仍允许请求占用8951毫秒:

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

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

  

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

这不是我正在寻找的。

是否可以在凤凰城设置请求超时?

2 个答案:

答案 0 :(得分:1)

这绝不是web服务器/框架的责任。牛仔对于应用程序中发生的事情没有任何线索(也不应该!),提供连接。凤凰城可以照顾到这一点,但它会违反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

旁注:当然,如果您需要在整个应用程序中使用此行为,只需声明一个宏,或者说。

答案 1 :(得分:0)

如果是这样。

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

不起作用。尝试更改为。

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