phoenix
phoenix copied to clipboard
`websocket: [fullsweep_after: ...]` not applied to websocket processes with high memory use
Environment
erlang: 24.3.4
elixir: 1.13.0
Cowboy: 2.9.0
plug_cowboy: 2.5.2
phoenix: 1.6.9
OS: Ubuntu 22.04
Related issue: https://github.com/phoenixframework/phoenix/issues/4613
Expected behavior
Setting websocket: [fullsweep_after: 0] on sockets should ideally apply the process flag to the {:cowboy_websocket, :loop, 3} process that has high memory usage and often needs a forced garbage collection.
Actual behavior
When dealing with very large payloads {:cowboy_websocket, :loop, 3} processes accumulate memory usage that lead to OOM errors.

fullsweep_after flag introduced here is only applied to children of the offending processes. Running manual GCs of said processes temporarily fixes the issue.
Inspecting process tree at the time :fullsweep_after is applied:
[
...
dictionary: [
"$initial_call": {:cowboy_stream_h, :request_process, 3},
"$ancestors": [#PID<0.5297.0>, ...]
],
garbage_collection: [
fullsweep_after: 0,
...
]
]
Parent (the one with high memory usage)
iex(14)> Process.info(pid(0, 5297, 0))
[
current_function: {:cowboy_websocket, :loop, 3},
dictionary: [
"$initial_call": {:cowboy_clear, :connection_process, 4},
"$ancestors": [...]
],
trap_exit: true,
garbage_collection: [
fullsweep_after: 65535, <<< would like to have this overriden to 0
...
]
]
Any other suggestions on how to deal with this without manual intervention are welcome.