[erlang-questions] Why isn't 'EXIT' message being received/processed?

Youngkin, Rich richard.youngkin@REDACTED
Tue Feb 17 23:25:21 CET 2015


Hi,

I've got an app that spawn_links processes with trap_exit. I'm killing the
linked processes but the monitoring process isn't always receiving the
'EXIT' message.  Here are some code snippets:

...
  process_flag(trap_exit, true),
  link(Connection),
  link(Channel),
...

loop(State) ->
  ...
  {'EXIT', What, Reason} ->
    do_something_smart();

  ...

Connection and Channel are a RabbitMQ connection and channel (although
that's not necessarily important to know). I'm manually running "force
close" on the connection via the RabbitMQ admin interface to trigger the
'EXIT'.  In one case the 'EXIT' message is received and in the other case
it isn't. Here are more code snippets to illustrate this (same loop/1
function as above):

loop(#state{channel=Channel, delay_ack= DelayAck} = State) ->
  ...

  {#'basic.deliver'{delivery_tag=DeliveryTag}, Content} ->
    ... do something with the content
    case DelayAck of
      true ->
        timer:sleep(500), %% allow time for 'EXIT' to arrive in the mailbox
before "ack_delivery" message
        self() ! {ack_delivery, Channel, DeliveryTag},
        loop(State);
      _ ->
       amqp_channel:call(Channel, #'basic.ack'{delivery_tag=DeliveryTag}),
       loop(State)
    end;

  {ack_delivery, Channel, DeliveryTag} ->
    timer:sleep(50), %% ack delay
    amqp_channel:call(Channel, #'basic.ack'{delivery_tag=DeliveryTag}),
    loop(State);

  ...

In the above snippet DelayAck specifies whether the actual ack happens
immediately or as a result of sending another message through loop/1.
When DelayAck is false the 'EXIT' message is received as expected. When
DelayAck is true there is a sleep of 500ms in order to allow the 'EXIT' to
arrive in the mailbox before the {ack_delivery, Channel, DeliveryTag}
message. But in this case the 'EXIT' message isn't received. The process
instead fails with a "noproc" when invoking amqp_channel:call/2 in
{ack_delivery...}. This makes sense since the Channel is now invalid, but I
did expect 'EXIT' to be received first thereby avoiding this failure.
Increasing the sleep before sending the {ack_delivery...} message doesn't
make any difference (except to delay the "noproc" failure). The behavior
described in this paragraph is consistent across several test runs.

What would explain why the 'EXIT' message isn't received (ahead of the
ack_delivery message, or even at all) in the DelayAck case?

Thanks,
Rich
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20150217/4f4242ae/attachment.htm>


More information about the erlang-questions mailing list