When the server initiates an AMQP connection close, it sends a Connection.Close frame to the client. When it receives one, the Erlang client amqp_gen_connection process does the following steps:
It notifies the amqp_channels_manager process, asking channels to be terminated.
It waits for channels to terminate.
Here, the channels are expected to terminate before the TCP connection is closed. When this happens in this order, Everything Is Fine™.
However, when the TCP connection is closed before channel processes had a chance to terminate, the connection process exits. Because the the amqp_channel_sup supervisor, managed by the amqp_channel_sup_sup supervisor, has a restart strategy of brutal_kill, this supervisor and all its children (including the channel process) are killed.
From the rabbitmq-federation plugin PoV, the link process crashes with the reason {upstream_channel_down, killed} or {downstream_channel_down, killed}.
I recall we had to fix a very similar issue in the server where channel shutdown and socket termination messages competed and produced confusing connection process crashes. So this makes sense 👍.
When the server initiates an AMQP connection close, it sends a
Connection.Close
frame to the client. When it receives one, the Erlang clientamqp_gen_connection
process does the following steps:amqp_channels_manager
process, asking channels to be terminated.Here, the channels are expected to terminate before the TCP connection is closed. When this happens in this order, Everything Is Fine™.
However, when the TCP connection is closed before channel processes had a chance to terminate, the connection process exits. Because the the
amqp_channel_sup
supervisor, managed by theamqp_channel_sup_sup
supervisor, has a restart strategy ofbrutal_kill
, this supervisor and all its children (including the channel process) are killed.From the rabbitmq-federation plugin PoV, the link process crashes with the reason
{upstream_channel_down, killed}
or{downstream_channel_down, killed}
.