rabbitmq / rabbitmq-server

Open source RabbitMQ: core server and tier 1 (built-in) plugins
https://www.rabbitmq.com/
Other
12.13k stars 3.91k forks source link

Multiple channel interceptors on the same method #824

Open gmr opened 8 years ago

gmr commented 8 years ago

I was testing interceptors (rabbitmq_message_timestamp, rabbitmq_routing_node_stamp) with 3.6.2. When both are enabled, attempts to open channels cause the connection to crash.

My understanding based upon the documentation is that only one interceptor can register for a method. My expectation of the behavior would be that if two interceptors enabled on a single method, one would fail to be registered and the failure would be logged, not that any connection to RabbitMQ would crash.

In my case, I was creating a "kitchen sink" RabbitMQ docker image with all plugins and didn't realize the behavior of enabling both of the interceptors would make RabbitMQ virtually unusable. I don't think that's a great user experience and RabbitMQ should not blow up when such things happen.

At the very least, some sort of logging on startup that lets the user know that the two plugins they installed conflict with each other and will blow up any RabbitMQ connection that tries to open a channel above 0.

Crash Log:

=CRASH REPORT==== 5-Jun-2016::18:18:08 ===
  crasher:
    initial call: rabbit_reader:init/4
    pid: <0.15054.0>
    registered_name: []
    exception error: no match of right hand side value 
                     {error,
                      {'EXIT',
                       {{badmatch,
                         {error,
                          {{amqp_error,internal_error,
                            "Interceptor: more than one module handles {set,1,16,16,8,80,48,\n                                           {[],[],[],[],[],[],[],[],[],[],[],\n                                            [],[],[],[],[]},\n                                           {{[],[],[],[],[],[],[],[],\n                                             ['basic.publish'],\n                                             [],[],[],[],[],[],[]}}}\n",
                            none},
                           {child,undefined,channel,
                            {rabbit_channel,start_link,
                             [1,<0.15054.0>,<0.15521.0>,<0.15054.0>,
                              <<"172.17.0.1:55884 -> 172.17.0.2:5672">>,
                              rabbit_framing_amqp_0_9_1,
                              {user,<<"guest">>,
                               [administrator],
                               [{rabbit_auth_backend_internal,none}]},
                              <<"/">>,
                              [{<<"publisher_confirms">>,bool,true},
                               {<<"exchange_exchange_bindings">>,bool,true},
                               {<<"basic.nack">>,bool,true},
                               {<<"consumer_cancel_notify">>,bool,true},
                               {<<"connection.blocked">>,bool,true},
                               {<<"authentication_failure_close">>,bool,true}],
                              <0.15055.0>,<0.15522.0>]},
                            intrinsic,70000,worker,
                            [rabbit_channel]}}}},
                        [{rabbit_channel_sup,start_link,1,
                          [{file,"src/rabbit_channel_sup.erl"},{line,67}]},
…

=SUPERVISOR REPORT==== 5-Jun-2016::18:18:08 ===
     Supervisor: {<0.15052.0>,rabbit_connection_sup}
     Context:    child_terminated
     Reason:     {badmatch,
                  {error,
                   {'EXIT',
                    {{badmatch,
                      {error,
                       {{amqp_error,internal_error,
                         "Interceptor: more than one module handles {set,1,16,16,8,80,48,\n                                           {[],[],[],[],[],[],[],[],[],[],[],\n                                            [],[],[],[],[]},\n                                           {{[],[],[],[],[],[],[],[],\n                                             ['basic.publish'],\n                                             [],[],[],[],[],[],[]}}}\n",
                         none},
                        {child,undefined,channel,
                         {rabbit_channel,start_link,
                          [1,<0.15054.0>,<0.15521.0>,<0.15054.0>,
                           <<"172.17.0.1:55884 -> 172.17.0.2:5672">>,
                           rabbit_framing_amqp_0_9_1,
                           {user,<<"guest">>,
                            [administrator],
                            [{rabbit_auth_backend_internal,none}]},
                           <<"/">>,
                           [{<<"publisher_confirms">>,bool,true},
                            {<<"exchange_exchange_bindings">>,bool,true},
                            {<<"basic.nack">>,bool,true},
                            {<<"consumer_cancel_notify">>,bool,true},
                            {<<"connection.blocked">>,bool,true},
                            {<<"authentication_failure_close">>,bool,true}],
                           <0.15055.0>,<0.15522.0>]},
                         intrinsic,70000,worker,
                         [rabbit_channel]}}}},
                     [{rabbit_channel_sup,start_link,1,
                       [{file,"src/rabbit_channel_sup.erl"},{line,67}]},
…
michaelklishin commented 8 years ago

Thanks. Folding over a collection of interceptors should be doable and possibly even easier than telling if a plugin provides any interceptors.