I have Phoenix application with complex business logic behind HTTP endpoint. This logic includes interaction with database and few external services and once request processing has been started it must not be interrupted till all operations will be done.
But it seems like Cowboy or Ranch kills request handler process (Phoenix controller) if client suddenly closes connection, which leads to partially executed business process. To debug this I have following code in controller action:
Process.flag(:trap_exit, true)
receive do
msg -> Logger.info("Message: #{inspect msg}")
after
10_000 -> Logger.info("Timeout")
end
And to simulate connection closing I set timeout: curl --request POST 'http://localhost:4003' --max-time 3
.
After 3 seconds in IEx console I see that process is about to exit: Message: {:EXIT, #PID<0.4196.0>, :shutdown}
.
So I need to make controller complete its job and reply to client if it is still there or do nothing if connection is lost. Which will be the best way to achieve this:
- trap exits in controller action and ignore exit messages;
- spawn not linked
Task
in controller action and wait for its results; - somehow configure Cowboy/Ranch so it will not kill handler process, if it is possible (tried
exit_on_close
with no luck)?