我希望请求在一段时间后超时,比如说20秒。如果应用程序发送响应的时间超过20秒,Phoenix应该取消执行并立即回复一些错误(最好是HTTP 503)。
我已经浏览过Phoenix文档,但无法找到任何请求超时选项。看起来牛仔有一个:timeout
选项,我尝试将其设置为10毫秒,但它仍允许请求占用8951毫秒:
config :app, SomeApp.Endpoint,
http: [port: 4000, timeout: 10]
事实证明,牛仔文档将此选项定义为:
在Cowboy关闭连接之前没有请求的毫秒时间。
这不是我正在寻找的。
是否可以在凤凰城设置请求超时?
答案 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
旁注:当然,如果您需要在整个应用程序中使用此行为,只需声明一个宏,或者说。
答案 1 :(得分:0)
如果是这样。
config :app, SomeApp.Endpoint,
http: [port: 4000, timeout: 10]
不起作用。尝试更改为。
config :app, SomeApp.Endpoint,
http: [port: 4000, protocol_options: [idle_timeout: 10_000]]