Git Product home page Git Product logo

rabbitmq-erlang-client's Introduction

rabbitmq-erlang-client's People

Contributors

0x6e6562 avatar acogoluegnes avatar ayanda-d avatar carlhoerberg avatar cooper6581 avatar danielwhite avatar dcorbacho avatar dpw avatar dsrosario avatar dumbbell avatar essen avatar essiene avatar fenollp avatar gerhard avatar gmr avatar gotthardp avatar hairyhum avatar jsoref avatar kjnilsson avatar lazedo avatar lukebakken avatar michaelklishin avatar nyczol avatar pjk25 avatar priviterag avatar rade avatar reepong avatar tonyg avatar velimir avatar videlalvaro avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rabbitmq-erlang-client's Issues

rabbitmq-erlang-client should define deps of syntax_tools and compiler

with amqp_client in DEPS, release built by erlang.mk can't start:

{{function_clause,[{amqp_gen_connection,terminate,[{undef,[{erl_syntax,form_list,[[{attribute,1,file,{"src/time_compat.erl",1}},...

after adding syntax_tools into LOCAL_DEPS:

{{function_clause,[{amqp_gen_connection,terminate,[{undef,[{compile,forms,[[{attribute,1,file,{"src/time_compat.erl",1}},...

adding compiler into LOCAL_DEPS and it works

Race condition during a channel failure handling

While working on moving the testsuite to common_test (#39), I got transient failures with cases testing channel-level errors, especially:

  • shortstr_overflow_property
  • shortstr_overflow_field
  • channel_writer_death

The problem comes from a race condition in the supervision tree for a particular channel when using a network connection (as opposed to direct Erlang communication). The supervision tree looks like this:

amqp_channel_sup
|-- amqp_gen_consumer
|-- amqp_channel
`-- rabbit_writer

amqp_channel sends commands to rabbit_writer who then sends frames on the network. If an error occurs in rabbit_writer, it sends a channel_exit message to amqp_channel and exits with the reason normal. amqp_channel receives the notification and exits with an error. Then normal supervision tree termination continues.

After this kind of error, the connection can't be trusted anymore so it must be taken down. This is the repsonsibility of amqp_channels_manager which is part of a larger supervision tree dedicated to a connection:

amqp_connection_sup
|-- amqp_connection_type_sup
|   |-- amqp_channel_sup_sup
|   |   `-- amqp_channel_sup
|   |       `-- ... # The channel supervision tree described above
|   |-- amqp_channels_manager
|   |-- rabbit_writer
|   |-- amqp_main_reader
|   |-- rabbit_heartbeat
|   `-- rabbit_heartbeat
`-- amqp_gen_connection

So when a channel exits with an error, amqp_channels_manager terminates the connection.

However, this relies on the fact that amqp_channel_sup is notified of amqp_channel exit before rabbit_writer exit. If amqp_channel_sup notices the exit of rabbit_writer first (with reason normal), it terminates the supervision tree: amqp_channel exits with the reason shutdown and amqp_channels_manager considers this an expected termination. The connection is left alone, which is bad.

The issue is that rabbit_writer has its restart type set to intrinsic, which means that no matter its exit reason, if this child exits, the whole supervision tree must be terminated. This is wrong in this situation because rabbit_writer always sends a message to amqp_channel to notify its exit.

By using a restart type of transient, rabbit_writer still exits but the supervision tree is not taken down. Instead amqp_channel has time to receive the message from rabbit_writer and exits with an error.

Capability to access connection properties (direct connection)

The amqp_connection returns a bunch of information about connection itself, but in some cases there is the need to get even more information that is returned using info keys. Using the info_key user for instance, it will return filtered information about the user:
i(user, #state{params = P}) -> P#amqp_params_direct.username;

The problem is that the direct connection returns much more info about the user, like Tags generated during authentication process. The idea is to create a way to allow user to access the entire content from connection state, with something like:
i(state, State) -> State;

The main use, on my case, is to allow mqtt plugin to execute check_topic_access without having to execute user_authentication multiple times.

What do you guys think?

Test failures on master

no_vhost and non_existent_vhost fail reliably due to unexpected return code when a vhost isn't found.

what does the error mean:"unexpected_delivery_and_no_default_consumer"

I use rabbitmq-erlang-client rabbitmq_2.7.0 in my production env. Recently, I have found some error as "unexpected_delivery_and_no_default_consumer" in my server app log.

2016-08-26 15:25:00.465 [error] <0.1623.0> CRASH REPORT Process <0.1623.0> with 0 neighbours exited with reason: {unexpected_delivery_and_no_default_consumer,{gen_server2,call,[<0.1622.0>,{consumer_call,{'basic.deliver',<<"amq.ctag-2I715Fu1Q2m9AHgrhlN1Og">>,15804,false,<<"be3_statics_exchange">>,<<"be3_statics">>},{amqp_msg,{'P_basic',undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined},<<131,104,5,100,0,14,115,116,97,116,105,99,115,95,111,110,108,105,110,101,109,0,0,0,3,105,111,115,97,0,97,0,98,87,192,95,76>>}},infinity]}} in gen_server:terminate/7 line 826

rabbitmq consumer res:

be3_statics    amq.ctag-hQQmjXButGMUQuHJQmSc4A true    0   []
be3_statics    amq.ctag-f4VlH3_O5QBKXvyTl8xq8Q true    0   []
be3_statics     amq.ctag-iY9xwuglKAkTS0baSZ8uyw true    0   []
be3_statics    amq.ctag-uB1RG3JgzGi_YA6Qqy8G6w true    0   []
be3_statics     amq.ctag-5VUGfvW4L3eO-7rVjG1Q0w true    0   []
be3_statics    amq.ctag-OiWZBasEegvwJhB2taMayA true    0   []
be3_statics     amq.ctag-ogUoP0BumVmsP2zaYiFPOg true    0   []
be3_statics     amq.ctag-VcE4XGHk1DB5jqclnQDqhQ true    0   []
be3_statics     amq.ctag-9TDHYscJrMun559kduyvEA true    0   []
be3_statics     amq.ctag-g-M6m686GQOqvgeHEvzO2g true    0   []

my consumer config is as follows

  #'basic.consume_ok'{consumer_tag = Tag} = amqp_channel:subscribe(Channel, #'basic.consume'{queue = Queue}, self()),   %% no_ack = false

Also, I do not call the method 'basic.cancel'.

After viewing source code, I know it is happened when tag in Msg is not in consumer tags. I wonder

  • What is the root cause for the error: "unexpected_delivery_and_no_default_consumer"?
  • How to avoid the error?

Thanks a lot.

Crash dump running make

OTP-18.1.3 installed through erln8. Checked out master of this repo and ran make:

$ make
 DEP    rabbit_common
(no error logger present) error: <0.0.0>

Crash dump is being written to: erl_crash.dump...done
System process <0.0.0> terminated: {function_clause,[{init,prepare_run_args,[{eval,[<<9,65,112,112,83,114,99,79,117,116,32,61,32,34,47,104,111,109,101,47,116,114,105,115,116,97,110,47,114,97,98,98,105,116,109,113,45,101,114,108,97,110,103,45,99,108,105,101,110,116,47,100,101,112,115,47,114,97,98,98,105,116,95,99,111,109,109,111,110,47,115,114,99,47,114,97,98,98,105,116,95,99,111,109,109,111,110,46,97,112,112,46,115,114,99,34,44,9,65,112,112,83,114,99,73,110,32,61,32,99,97,115,101,32,102,105,108,101,108,105,98,58,105,115,95,114,101,103,117,108,97,114,40,65,112,112,83,114,99,79,117,116,41,32,111,102,32,102,97,108,115,101,32,45,62,32,34,47,104,111,109,101,47,116,114,105,115,116,97,110,47,114,97,98,98,105,116,109,113,45,101,114,108,97,110,103,45,99,108,105,101,110,116,47,100,101,112,115,47,114,97,98,98,105,116,95,99,111,109,109,111,110,47,101,98,105,110,47,114,97,98,98,105,116,95,99,111,109,109,111,110,46,97,112,112,34,59,32,116,114,117,101,32,45,62,32,65,112,112,83,114,99,79,117,116,32,101,110,100,44,9,99,97,115,101,32,102,105,108,101,108,105,98,58,105,115,95,114,101,103,117,108,97,114,40,65,112,112,83,114,99,73,110,41,32,111,102,9,9,102,97,108,115,101,32,45,62,32,111,107,59,9,9,116,114,117,101,32,45,62,9,9,9,123,111,107,44,32,91,123,97,112,112,108,105,99,97,116,105,111,110,44,32,114,97,98,98,105,116,95,99,111,109,109,111,110,44,32,76,48,125,93,125,32,61,32,102,105,108,101,58,99,111,110,115,117,108,116,40,65,112,112,83,114,99,73,110,41,44,9,9,9,76,49,32,61,32,108,105,115,116,115,58,107,101,121,115,116,111,114,101,40,109,111,100,117,108,101,115,44,32,49,44,32,76,48,44,32,123,109,111,100,117,108,101,115,44,32,91,93,125,41,44,9,9,9,76,50,32,61,32,99,97,115,101,32,108,105,115,116,115,58,107,101,121,102,105,110,100,40,118,115,110,44,32,49,44,32,76,49,41,32,111,102,32,123,95,44,32,103,105,116,125,32,45,62,32,108,105,115,116,115,58,107,101,121,114,101,112,108,97,99,101,40,118,115,110,44,32,49,44,32,76,49,44,32,123,118,115,110,44,32,34,103,105,116,34,125,41,59,32,95,32,45,62,32,76,49,32,101,110,100,44,9,9,9,76,51,32,61,32,99,97,115,101,32,108,105,115,116,115,58,107,101,121,102,105,110,100,40,114,101,103,105,115,116,101,114,101,100,44,32,49,44,32,76,50,41,32,111,102,32,102,97,108,115,101,32,45,62,32,91,123,114,101,103,105,115,116,101,114,101,100,44,32,91,93,125,124,76,50,93,59,32,95,32,45,62,32,76,50,32,101,110,100,44,9,9,9,111,107,32,61,32,102,105,108,101,58,119,114,105,116,101,95,102,105,108,101,40,65,112,112,83,114,99,79,117,116,44,32,105,111,95,108,105,98,58,102,111,114,109,97,116,40,34,126,112,46,126,110,34,44,32,91,123,97,112,112,108,105,99,97,116,105,111,110,44,32,114,97,98,98,105,116,95,99,111,109,109,111,110,44,32,76,51,125,93,41,41,44,9,9,9,99,97,115,101,32,65,112,112,83,114,99,79,117,116,32,111,102,32,65,112,112,83,114,99,73,110,32,45,62,32,111,107,59,32,95,32,45,62,32,111,107,32,61,32,102,105,108,101,58,100,101,108,101,116,101,40,65,112,112,83,114,99,73,110,41,32,101,110,100,9,101,110,100,44,9,104,97,108,116,40,41>>,<<"erlang.mk">>,<<"erlang.mk">>]}],[]},{init,map,2,[]},{init,boot,1,[]}]}
make[1]: Entering directory '/home/tristan/rabbitmq-erlang-client/deps/rabbit_common'
 DEP    rabbitmq_codegen

Crash dump is being written to: erl_crash.dump...done
System process <0.0.0> terminated: {function_clause,[{init,prepare_run_args,[{eval,[<<9,85,112,100,97,116,101,77,111,100,117,108,101,115,32,61,32,102,117,110,40,65,112,112,41,32,45,62,9,9,99,97,115,101,32,102,105,108,101,108,105,98,58,105,115,95,114,101,103,117,108,97,114,40,65,112,112,41,32,111,102,9,9,9,102,97,108,115,101,32,45,62,32,111,107,59,9,9,9,116,114,117,101,32,45,62,9,9,9,9,123,111,107,44,32,91,123,97,112,112,108,105,99,97,116,105,111,110,44,32,39,114,97,98,98,105,116,109,113,95,99,111,100,101,103,101,110,39,44,32,76,48,125,93,125,32,61,32,102,105,108,101,58,99,111,110,115,117,108,116,40,65,112,112,41,44,9,9,9,9,77,111,100,115,32,61,32,102,105,108,101,108,105,98,58,102,111,108,100,95,102,105,108,101,115,40,34,47,104,111,109,101,47,116,114,105,115,116,97,110,47,114,97,98,98,105,116,109,113,45,101,114,108,97,110,103,45,99,108,105,101,110,116,47,100,101,112,115,47,114,97,98,98,105,116,109,113,95,99,111,100,101,103,101,110,47,115,114,99,34,44,32,34,92,92,46,101,114,108,49,54,49,55,53,34,44,32,116,114,117,101,44,9,9,9,9,9,102,117,110,32,40,70,44,32,65,99,99,41,32,45,62,32,91,108,105,115,116,95,116,111,95,97,116,111,109,40,102,105,108,101,110,97,109,101,58,114,111,111,116,110,97,109,101,40,102,105,108,101,110,97,109,101,58,98,97,115,101,110,97,109,101,40,70,41,41,41,124,65,99,99,93,32,101,110,100,44,32,91,93,41,44,9,9,9,9,76,32,61,32,108,105,115,116,115,58,107,101,121,115,116,111,114,101,40,109,111,100,117,108,101,115,44,32,49,44,32,76,48,44,32,123,109,111,100,117,108,101,115,44,32,77,111,100,115,125,41,44,9,9,9,9,111,107,32,61,32,102,105,108,101,58,119,114,105,116,101,95,102,105,108,101,40,65,112,112,44,32,105,111,95,108,105,98,58,102,111,114,109,97,116,40,34,126,112,46,126,110,34,44,32,91,123,97,112,112,108,105,99,97,116,105,111,110,44,32,39,114,97,98,98,105,116,109,113,95,99,111,100,101,103,101,110,39,44,32,76,125,93,41,41,9,9,101,110,100,9,101,110,100,44,9,85,112,100,97,116,101,77,111,100,117,108,101,115,40,34,47,104,111,109,101,47,116,114,105,115,116,97,110,47,114,97,98,98,105,116,109,113,45,101,114,108,97,110,103,45,99,108,105,101,110,116,47,100,101,112,115,47,114,97,98,98,105,116,109,113,95,99,111,100,101,103,101,110,47,101,98,105,110,47,114,97,98,98,105,116,109,113,95,99,111,100,101,103,101,110,46,97,112,112,34,41,44,9,104,97,108,116,40,41>>,<<"erlang.mk">>,<<"erlang.mk">>]}],[]},{init,map,2,[]},{init,boot,1,[]}]}
../../erlang.mk:4671: recipe for target '/home/tristan/rabbitmq-erlang-client/deps/rabbitmq_codegen' failed
make[1]: *** [/home/tristan/rabbitmq-erlang-client/deps/rabbitmq_codegen] Error 1
make[1]: Leaving directory '/home/tristan/rabbitmq-erlang-client/deps/rabbit_common'
erlang.mk:4096: recipe for target 'deps' failed
make: *** [deps] Error 2

header value `nil` causes error (but `publish` reports `:ok`)

Hi folks,

I'm pretty sure this is a bug, but I just want to make sure before I make an attempt to fix it.

If I publish a message with a header with value nil, then I get return value :ok, but the message isn't delivered to rabbitmq at all. Instead some process dies, and with it, the message.

Here's a simple example (apologies, this is Elixir code written with the AMQP library, but it calls through almost directly to :amqp_client):

AMQP.Basic.publish(ch, "requests", "", "foo", [headers: {"foo", :longstr, nil}])
:ok

And the output from handle_sasl_reports: true

iex(7)> [error] Process #PID<0.924.0> terminating
** (FunctionClauseError) no function clause matching in :rabbit_binary_generator.generate_table/1
    (rabbit_common) /apps/public_interface/deps/rabbit_common/src/rabbit_binary_generator.erl:146: :rabbit_binary_generator.generate_table({"foo", :longstr
, nil})
    (rabbit_common) /apps/public_interface/deps/rabbit_common/src/rabbit_framing_amqp_0_9_1.erl:1190: :rabbit_framing_amqp_0_9_1.encode_properties/1
    (rabbit_common) /apps/public_interface/deps/rabbit_common/src/rabbit_binary_generator.erl:190: :rabbit_binary_generator.ensure_content_encoded/2
    (rabbit_common) /apps/public_interface/deps/rabbit_common/src/rabbit_binary_generator.erl:68: :rabbit_binary_generator.build_simple_content_frames/4
    (rabbit_common) /apps/public_interface/deps/rabbit_common/src/rabbit_writer.erl:311: :rabbit_writer.assemble_frames/5
    (rabbit_common) /apps/public_interface/deps/rabbit_common/src/rabbit_writer.erl:341: :rabbit_writer.internal_send_command_async/3
    (rabbit_common) /apps/public_interface/deps/rabbit_common/src/rabbit_writer.erl:209: :rabbit_writer.handle_message/3
    (rabbit_common) /apps/public_interface/deps/rabbit_common/src/rabbit_writer.erl:193: :rabbit_writer.mainloop1/2
    (rabbit_common) /apps/public_interface/deps/rabbit_common/src/rabbit_writer.erl:184: :rabbit_writer.mainloop/2
    (stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
Initial Call: :rabbit_writer.enter_mainloop/2
Ancestors: [#PID<0.921.0>, #PID<0.795.0>, #PID<0.793.0>, #PID<0.792.0>, :amqp_sup, #PID<0.696.0>]
Message Queue Length: 0
Messages: []
Links: [#PID<0.921.0>]
Dictionary: [process_name: {:rabbit_writer, {"client 172.20.0.4:57073 -> 172.20.0.3:5672", 4}}]
Trapping Exits: false
Status: :running
Heap Size: 2586
Stack Size: 27
Reductions: 406
[error] Child :writer of Supervisor #PID<0.921.0> (:amqp_channel_sup) terminated
** (exit) an exception was raised:
    ** (FunctionClauseError) no function clause matching in :rabbit_binary_generator.generate_table/1
        (rabbit_common) /apps/public_interface/deps/rabbit_common/src/rabbit_binary_generator.erl:146: :rabbit_binary_generator.generate_table({"foo", :lon
gstr, nil})
        (rabbit_common) /apps/public_interface/deps/rabbit_common/src/rabbit_framing_amqp_0_9_1.erl:1190: :rabbit_framing_amqp_0_9_1.encode_properties/1
        (rabbit_common) /apps/public_interface/deps/rabbit_common/src/rabbit_binary_generator.erl:190: :rabbit_binary_generator.ensure_content_encoded/2
        (rabbit_common) /apps/public_interface/deps/rabbit_common/src/rabbit_binary_generator.erl:68: :rabbit_binary_generator.build_simple_content_frames/
4
        (rabbit_common) /apps/public_interface/deps/rabbit_common/src/rabbit_writer.erl:311: :rabbit_writer.assemble_frames/5
        (rabbit_common) /apps/public_interface/deps/rabbit_common/src/rabbit_writer.erl:341: :rabbit_writer.internal_send_command_async/3
        (rabbit_common) /apps/public_interface/deps/rabbit_common/src/rabbit_writer.erl:209: :rabbit_writer.handle_message/3
        (rabbit_common) /apps/public_interface/deps/rabbit_common/src/rabbit_writer.erl:193: :rabbit_writer.mainloop1/2
        (rabbit_common) /apps/public_interface/deps/rabbit_common/src/rabbit_writer.erl:184: :rabbit_writer.mainloop/2
        (stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3
Pid: #PID<0.924.0>
Start Call: :rabbit_writer.start_link(#Port<0.27962>, 4, 131072, :rabbit_framing_amqp_0_9_1, #PID<0.923.0>, {"client 172.20.0.4:57073 -> 172.20.0.3:5672", 
4})
Restart: :transient
Shutdown: 30000
Type: :worker
[error] Child :writer of Supervisor #PID<0.921.0> (:amqp_channel_sup) caused shutdown
** (exit) :reached_max_restart_intensity
Start Call: :rabbit_writer.start_link(#Port<0.27962>, 4, 131072, :rabbit_framing_amqp_0_9_1, #PID<0.923.0>, {"client 172.20.0.4:57073 -> 172.20.0.3:5672", 
4})
Restart: :transient
Shutdown: 30000
Type: :worker

Expected behaviour would be an error return value.

I'd like to make an attempt to fix this issue, but I thought I'd ask here first whether anyone had any feedback. This is quite frustrating to debug if you're just getting started.

add rebar.config to makefile

Hi,
how about adding

# Generate rebar.config on build.
app:: rebar.config

to the makefile the way ninenines does for cowboy ?

compile error

Hi! the latest code can not compile.

===> Compiling /home/dcy/hisir/Server/hisir_msgs/_build/default/lib/amqp_client/src/amqp_connection_type_sup.erl failed
/home/dcy/hisir/Server/hisir_msgs/_build/default/lib/amqp_client/src/amqp_connection_type_sup.erl:51: undefined macro 'WORKER_WAIT'

badmatch in amqp_network_connection:handshake causes amqp_connection:start to fail

We sometimes get the following error in our application which seems to occur because an error happens during the connection handshake.

2014-11-29 02:29:38 =ERROR REPORT====
** Generic server <0.248.0> terminating 
** Last message in was connect
** When Server state == {<0.230.0>,{amqp_params_network,<<"guest">>,<<"guest">>,<<"tasks">>,"mq.example.com",5672,0,0,0,infinity,none,[#Fun<amqp_auth_mechanisms.plain.3>,#Fun<amqp_auth_mechanisms.amqplain.3>],[],[]}}
** Reason for termination == 
** {function_clause,[{amqp_gen_connection,terminate,[{{badmatch,{error,closed}},[{amqp_network_connection,handshake,2,[{file,"src/amqp_network_connection.erl"},{line,190}]},{amqp_network_connection,try_handshake,3,[{file,"src/amqp_network_connection.erl"},{line,174}]},{amqp_gen_connection,handle_call,3,[{file,"src/amqp_gen_connection.erl"},{line,171}]},{gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,580}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,237}]}]},{<0.230.0>,{amqp_params_network,<<"guest">>,<<"guest">>,<<"/">>,"localhost",5672,0,0,0,infinity,none,[#Fun<amqp_auth_mechanisms.plain.3>,#Fun<amqp_auth_mechanisms.amqplain.3>],[],[]}}],[{file,"src/amqp_gen_connection.erl"},{line,230}]},{gen_server,terminate,6,[{file,"gen_server.erl"},{line,721}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,237}]}]}

I'm not sure if it's a bug, or if we should be catching the issue in some other way? This code segment is pretty similar to what we have in production:

-module(client).

-include_lib("amqp_client/include/amqp_client.hrl").

-export([test/0]).

test() ->
    case amqp_connection:start(#amqp_params_network{}) of
        {ok, _Connection} -> "SUCCESS";
        {error, _Error} -> "FAILED"
    end.

Looking at the code at amqp_network_connection.erl , line 190, it seems that we are expecting that handshake_recv will only ever reply with a connection.start record, but intermittently our RabbitMQ machine fails at this point and the above error occurs.

Start = #'connection.start'{server_properties = ServerProperties,
                        mechanisms = Mechanisms} =
    handshake_recv('connection.start'),

Could someone please take a look and let me know if this is a bug in the library, or should our application be handling the badmatch condition in some other way?

Thanks

Mochiweb make

Dear experts,

I tried to develop a Mochiweb based application, that will use RabbitMQ,
So I put your git repo in my Mochiweb app's rebar.config such as below:

{deps, [
{mochiweb, ".", {git, "git://github.com/mochi/mochiweb.git", "master"}},
{rabbitmq, ".
", {git, "git://github.com/rabbitmq/rabbitmq-erlang-client.git", "master"}}
]}.

When I want to build my app, I managed to clone your project into my Mochiweb's deps folder but
I got an error like: {missing_app_file,"/home/...} during compile time.

Can you please come up with REBAR friendly version?

Currently, to continue my project, I just download your erlang-client lib, then dump it inside erlang lib folder,
but I thought of it as a non-elegant approach.

Thanks

The client fails to compile on Erlang/OTP release 19.x

Hi, just a quick heads up for things which will change in 19.x:

https://github.com/rabbitmq/rabbitmq-erlang-client/blob/master/include/amqp_gen_consumer_spec.hrl#L30-L42

The -spec(init/1 :: ...) form is supposedly going away and is not allowed anymore as a form. This means the current version of the amqp_client will not compile on this release. It is still some months out in the future, so there is no rush, but you may want to see if there are other places you get hit, eventually.

Enable heartbeats by default

Disabled heartbeats is not a great default.

Default values in the 10-20 seconds range work well for a lot of users, including those using Federation and Shovel plugins.

Issue with blocked connection

We had an issue with blocked connections which could cause the serious damage to your system.

Steps to replicate the issue

Step 1. create a test queue on Rabbit MQ

Let's name it test.

Step 2. simulate the blocked connection by setting lower memory threshold

For example, set the following value in your rabbitmq.config.

[
    {rabbit, [{vm_memory_high_watermark, {absolute, "10MiB"}}]}
].

Then restart RabbitMQ and try making a connection.
Then you will see the connection state is blocked when you check the connection on admin panel.

Step 3. try publish a message to the server

If you call the following code, it will never return.

test_blocked() ->
    {ok, Connection} =
        amqp_connection:start(#amqp_params_network{host = "localhost"}),
    {ok, Channel} = amqp_connection:open_channel(Connection),

    % Problem 1: I'd expect `call/3` to return `blocking` instead of `ok` but it returns `ok`
    ok = amqp_channel:call(Channel,
                           #'basic.publish'{
                               exchange = <<"">>,
                               routing_key = <<"test">>
                           },
                           #amqp_msg{payload = <<"Hello World!">>}),

    % Problem 2: The program will hang here. It will never return any value or raise an exception.
    ok = amqp_channel:close(Channel),
    ok.

Environment

I can reproduce the issue at least with:

  • OTP: 20
  • amqp_client and rabbit_common: 3.6.12
  • RabbitMQ server 3.6.6

no persistent=true for basic.publish?

In the examples (like elixer job queue) there is a section about message durability that seems to indicate that a restart will lose messages unless the messages are published with persistent=true. I'm unable to find any feature in the erlang client that supports this.

(Standalone repo) compilation failure in master

From a failed nightly build:

DEPEND amqp_client.d 
ERLC amqp_auth_mechanisms.erl amqp_channel.erl amqp_channel_sup.erl amqp_channel_sup_sup.erl amqp_channels_manager.erl amqp_client.erl amqp_connection.erl amqp_connection_sup.erl amqp_connection_type_sup.erl amqp_direct_connection.erl amqp_direct_consumer.erl amqp_gen_connection.erl amqp_gen_consumer.erl amqp_main_reader.erl amqp_network_connection.erl amqp_rpc_client.erl amqp_rpc_server.erl amqp_selective_consumer.erl amqp_sup.erl amqp_uri.erl rabbit_ct_client_helpers.erl rabbit_routing_util.erl uri_parser.erl 
src/rabbit_ct_client_helpers.erl:20: can't find include lib "amqp_client/include/amqp_client.hrl" 
src/rabbit_ct_client_helpers.erl:39: record amqp_params_network undefined 
src/rabbit_ct_client_helpers.erl:38: variable 'Port' is unused 
make: Leaving directory `/home/autobuild/rabbitmq-erlang-client-3.7.0.422/amqp_client-3.7.0.422-src' 
make[1]: *** [ebin/amqp_client.app] Error 1 
make: *** [app] Error 2 
make: *** [release-erlang-client-package] Error 2 
make: Leaving directory `/var/tmp/rabbit.16542/rabbitmq-public-umbrella' 

Using amqp_client as dependency - no debug_info in built modules

When starting erlang.mk project from scratch with amqp_client in dependencies, every module from this library is built without debug_info. Only amqp_client modules are affected, e.g. modules from rabbit_common has this option.

Minimal steps to reproduce:

mkdir amqp_test
cd amqp_test
wget https://raw.githubusercontent.com/ninenines/erlang.mk/master/erlang.mk
make -f erlang.mk bootstrap
perl -pi -e 's/^(?=include)/DEPS += amqp_client\n/' Makefile
make
make shell
% no debug_info for every module from amqp_client
proplists:get_value(options, amqp_channel:module_info(compile)). 

% but modules from other repos, e.g. from rabbit_common has debug_info
proplists:get_value(options, rabbit_channel:module_info(compile)).

Direct connections from outside of RabbitMQ will fail in stable

Direct connections work from within the broker itself, but any project which depends only on amqp_client is broken (like pma/amqp#73)

This happened because in rabbitmq/rabbitmq-common@81b5eab#diff-7159eb0974065867f293d7148ba5036aL1 rabbit_queue_collector module was removed from rabbit_common, but it's still being referenced here

{collector, {rabbit_queue_collector, start_link, [ConnName]},

gen_server2 and supervisor2 conflict

When I try to use both rabbitmq-erlang-client and riak-core a conflict is detect at release construction for gen_server2 and supervisor2 exists in both applications. I am not sure which party is supposed to fix this so I created a defect against both projects project. The resolution would probably be to prefix the custom behavior with the project name.

Direct connection reports server shutdown as error

amqp_direct_connection.handle_message({'DOWN', ...}, State) does not distinguish between the various reasons. As a consequence, the normal shutdown (rabbitmqctl stop) does generate an error report in the log file. (Can be reproduced by enabling the rabbitmq-metronome and setting log_levels={connection, debug}).

It think it would be better to handle the normal shutdown as a special case and not emit the error report.

some call errors

I'm trying to use -client , and confused about errors throwed by program.
I fllowed system_SUITE:queue_unbind/1 But errors are throwed when setting Exchange and Queue :

%% code
amqp_channel:call(Channel, #'exchange.declare'{exchange = X}),
amqp_channel:call(Channel, #'queue.declare'{queue = Q}),
%%  it throw me same errors again and again:
** Last message in was setup_exchange_queue
** When Server state == {state,
                            {amqp_params_network,<<"username">>,<<"password">>,
                                <<"/">>,"192.168.1.173",5672,0,0,10,infinity, 
                                none,
                                [#Fun<amqp_auth_mechanisms.plain.3>,
                                 #Fun<amqp_auth_mechanisms.amqplain.3>],
                                [],[]},
                            <0.74.0>,<0.83.0>,<<"amq.direct">>,<<"queue">>,
                            <<"my_queue">>,undefined,undefined}
** Reason for termination == 
** {{noproc,{gen_server,call,[<0.83.0>,{close,200,<<"Goodbye">>},infinity]}}, 
    [{gen_server,call,3,[{file,"gen_server.erl"},{line,212}]},
     {mrbq,terminate,2,[{file,"src/mrbq.erl"},{line,244}]},
     {gen_server,try_terminate,3,[{file,"gen_server.erl"},{line,643}]},
     {gen_server,terminate,7,[{file,"gen_server.erl"},{line,809}]},
     {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,240}]}]}
** exception exit: {noproc,
                       {gen_server,call,
                           [<0.83.0>,{close,200,<<"Goodbye">>},infinity]}}

code review amqp_channel.erl

%% call
call/2 -> gen_server:call/2  
handle_call/3 -> handle_method_to_server/6  

goto line 573, then line 888 ,and {noreply, State} returned for call as a result!!

What's wrong with above steps?
What should do to make it OK?

I have had tried cast/2,and no errors occur. But this is not what I need.

Log noise when direct connection is rejected due to missing vhost or insufficient permissions

Can be reproduced with rabbithole without running the setup steps:

2017-06-10 18:26:33.729 [error] <0.22639.157> Error on Direct connection <0.22639.157>
vhost not_found not found
2017-06-10 18:26:33.729 [error] <0.22639.157> ** Generic server <0.22639.157> terminating
** Last message in was connect
** When Server state == {state,amqp_direct_connection,{state,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined},undefined,{amqp_params_direct,<<"guest">>,<<"guest">>,not_found,rabbit@mercurio,none,[]},undefined,undefined,none,false}
** Reason for termination ==
** {{badrecord,amqp_adapter_info},[{amqp_direct_connection,i,2,[{file,"src/amqp_direct_connection.erl"},{line,117}]},{amqp_direct_connection,terminate,2,[{file,"src/amqp_direct_connection.erl"},{line,98}]},{gen_server,try_terminate,3,[{file,"gen_server.erl"},{line,629}]},{gen_server,terminate,7,[{file,"gen_server.erl"},{line,795}]},{gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,661}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,247}]}]}
2017-06-10 18:26:33.729 [error] <0.22639.157> CRASH REPORT Process <0.22639.157> with 0 neighbours exited with reason: bad record amqp_adapter_info in amqp_direct_connection:i/2 line 117 in gen_server:handle_msg/5 line 663
2017-06-10 18:26:33.729 [error] <0.22624.157> Supervisor {<0.22624.157>,amqp_connection_sup} had child connection started with amqp_gen_connection:start_link(<0.22580.157>, {amqp_params_direct,<<"guest">>,<<"guest">>,not_found,rabbit@mercurio,none,[]}) at <0.22639.157> exit with reason bad record amqp_adapter_info in amqp_direct_connection:i/2 line 117 in context child_terminated
2017-06-10 18:26:33.730 [error] <0.22624.157> Supervisor {<0.22624.157>,amqp_connection_sup} had child connection started with amqp_gen_connection:start_link(<0.22580.157>, {amqp_params_direct,<<"guest">>,<<"guest">>,not_found,rabbit@mercurio,none,[]}) at <0.22639.157> exit with reason reached_max_restart_intensity in context shutdown
2017-06-10 18:26:33.734 [error] <0.22628.157> Error on Direct connection <0.22628.157>
vhost not_found not found
2017-06-10 18:26:33.735 [error] <0.22628.157> ** Generic server <0.22628.157> terminating
** Last message in was connect
** When Server state == {state,amqp_direct_connection,{state,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined},undefined,{amqp_params_direct,<<"guest">>,<<"guest">>,not_found,rabbit@mercurio,none,[]},undefined,undefined,none,false}

This process termination is harmless (the connection is terminating anyway) but it would be great to avoid polluting the log with scary looking messages.

Couldn't build client from source tarball

After downloading and unpacking
https://www.rabbitmq.com/releases/rabbitmq-erlang-client/v3.5.7/amqp_client-3.5.7-src.tar.gz

make fails due to dependency on file named ../rabbitmq-server/generate_deps:

rm -f deps.mk
echo src/amqp_gen_connection.erl:src/amqp_rpc_client.erl:src/amqp_connection_sup.erl:src/amqp_gen_consumer.erl:src/amqp_channel_sup.erl:src/uri_parser.erl:src/amqp_sup.erl:src/amqp_connection_type_sup.erl:src/amqp_direct_connection.erl:src/amqp_network_connection.erl:src/amqp_uri.erl:src/amqp_rpc_server.erl:src/amqp_selective_consumer.erl:src/amqp_direct_consumer.erl:src/amqp_channel_sup_sup.erl:src/amqp_channels_manager.erl:src/rabbit_routing_util.erl:src/amqp_connection.erl:src/amqp_channel.erl:src/amqp_main_reader.erl:src/amqp_client.erl:src/amqp_auth_mechanisms.erl:include/rabbit_routing_prefixes.hrl:include/amqp_client.hrl:include/amqp_gen_consumer_spec.hrl:include/amqp_client_internal.hrl: | escript ../rabbitmq-server/generate_deps deps.mk ebin
escript: Failed to open file: ../rabbitmq-server/generate_deps
mkdir -p deps
rm -rf deps/rabbit_common-3.5.7
mkdir -p deps/rabbit_common-3.5.7
unzip -q -o dist/rabbit_common-3.5.7.ez -d deps
make: *** No rule to make target 'deps.mk', needed by 'ebin/amqp_gen_connection.beam'.  Stop.

Cannot connect to Broker

Hello,

I am unable to connect to RabbitMQ server using the erlang client. here's what I have done.

-module(producer).

-include("deps/amqp_client/include/amqp_client.hrl").

-export([produce/0]).

produce() ->
io:format("Trying to connect"),
{ok, Connection} = amqp_connection:start(#amqp_params_network{host="127.0.0.1"}).

Server is running on localhost (netstat output)

tcp 0 0 0.0.0.0:15672 0.0.0.0:* LISTEN 17887/beam.smp
tcp 0 0 127.0.0.1:5672 0.0.0.0:* LISTEN 17887/beam.smp
tcp 0 0 0.0.0.0:25672 0.0.0.0:* LISTEN 17887/beam.smp

I am facing the following error when I run producer:produce()

Trying to connect** exception exit: {noproc,{gen_server,call,
[amqp_sup,
{start_child,[{amqp_params_network,<<"guest">>,<<"guest">>,
<<"/">>,"127.0.0.1",5672,0,0,10,infinity,none,
[#Fun<amqp_auth_mechanisms.plain.3>,
#Fun<amqp_auth_mechanisms.amqplain.3>],
[],[]}]},
infinity]}}
in function gen_server:call/3 (gen_server.erl, line 212)
in call from amqp_connection:start/2 (src/amqp_connection.erl, line 174)
in call from producer:produce/0 (src/producer.erl, line 9)

Any idea why?

Thanks
Sammy

Why does killing a channel also kill the connection?

I've first created this issue on the elixir client for amqp (pma/amqp#112) but seeing it uses the erlang client underneed, I guess this is a better place for my question.

I'm going to repeat the issue here with the elixir syntax:

iex(27)> {:ok, conn} = AMQP.Connection.open(username: conf.username, password: conf.password, host: conf.host)
iex(28)> {:ok, chan1} = AMQP.Channel.open(conn)
iex(29)> {:ok, chan2} = AMQP.Channel.open(conn)
iex(30)> Process.exit(chan1, :kill)
iex(31)> Process.alive?(conn.pid)
false
iex(32)> Process.alive?(chan2.pid)
false

I'm surprised that killing a channel also kills the connection. If I'm correct it's perfectly ok to have multiple channels over the same connection, so in the above example I would expect the connection and channel2 to still be alive.

The other way around is of course fine, if the connection dies, all related channels should die.

/bin/sh: -c: line 0: syntax error near unexpected token `(' /bin/sh: -c: line 0: `echo " DEP " rabbit_common; fetch_url1='https://github.com/rabbitmq/rabbitmq-common';

make
/bin/sh: -c: line 0: syntax error near unexpected token `('
/bin/sh: -c: line 0: `echo " DEP   " rabbit_common;     fetch_url1='https://github.com/rabbitmq/rabbitmq-common'; fetch_url2='https://github.com/rabbitmq/rabbitmq-common.git'; if test "$fetch_url1" != 'https://github.com/rabbitmq/rabbitmq-erlang-client' && git clone -q -n -- "$fetch_url1" /usr/local/emqx_rabbitmq_hook/deps/amqp_client/deps/rabbit_common; then fetch_url="$fetch_url1"; push_url='https://github.com/rabbitmq/rabbitmq-common'; elif git clone -q -n -- "$fetch_url2" /usr/local/emqx_rabbitmq_hook/deps/amqp_client/deps/rabbit_common; then fetch_url="$fetch_url2"; push_url='[email protected]:rabbitmq/rabbitmq-common.git'; fi; cd /usr/local/emqx_rabbitmq_hook/deps/amqp_client/deps/rabbit_common && (  git checkout -q (no >/dev/null 2>&1 ||   git checkout -q branch) >/dev/null 2>&1 ||   git checkout -q master >/dev/null 2>&1 ||   git checkout -q master >/dev/null 2>&1 ||  (echo "error: no valid pathspec among:  (no branch) master master" 1>&2 && false) ) && (test "$fetch_url" = "$push_url" || git remote set-url --push origin "$push_url")'
make: *** No rule to make target `/usr/local/emqx_rabbitmq_hook/deps/amqp_client/deps/rabbit_common', needed by `deps'.  Stop.

Seqno reset to 1 on every confirm.select

The Confirms extension specification states:

Once a channel is in confirm mode, both the broker and the client count messages (counting starts at 1 on the first confirm.select).

That's what RabbitMQ does in rabbit_channel.erl:

  1. The sequence number is set to 1 during channel init:

    init(...) ->
        % ...
        State = #ch{state                   = starting,
                    % ...
                    confirm_enabled         = false,
                    publish_seqno           = 1,
  2. When a confirm.select is received, a single flag is toggled and the sequence number is left untouched:

    handle_method(#'confirm.select'{nowait = NoWait}, _, State) ->
        return_ok(State#ch{confirm_enabled = true},
                  NoWait, #'confirm.select_ok'{});

Unfortunately, rabbitmq-erlang-client resets the seqno to 1 with every confirm.select:

handle_method_to_server(...) ->
        case ... of
            {ok, _, ok} ->
                State1 = case {Method, State#state.next_pub_seqno} of
                             {#'confirm.select'{}, _} ->
                                                 % ^ The current seqno is ignored
                                 State#state{next_pub_seqno = 1};

The obvious consequence is that a second confirm.select from a client on a channel will lead to an inconsistency between the broker and the client counters. The client will receive ACKs for messages it never published yet.

The code should only set the seqno to 1 if it's set to 0 (0 meaning that confirms are disabled).

heartbeat=0 is negotiated but not actually respected

issue

An erlang client (or elixir that depends on this module) cannot be configured to run with disabled amqp-level heartbeats, and always accepts the default sent by the server - e.g. as recommended by cloudamqp. NB whether that is a good choice is not the intended purpose of this issue ;-)

In addition, I speculate that this same bug in the erlang client, causes the heartbeat sender on the server side to be disabled (as the client requested), but the erlang gen_server on the client side is incorrectly waiting the negotiated 2xHB duration for heartbeats inside rabbitmq-common, that cascades a timeout & subsequent socket termination, as the awaited heartbeat never comes.

rabbitmq docs

The client must be configured to request heartbeats. In RabbitMQ versions 3.0 and higher, the broker will attempt to negotiate heartbeats by default (although the client can still veto them). The timeout is in seconds, and default value is 60.

expected behaviour

Connecting to amqp://..?heartbeat=37 does show expected behaviour - client & server agree on the heartbeat frequency - as seen via tcpdump & validated in client amqp_connection:info(Conn, [heartbeat]). for client, and server in connection web ui.

Connecting to amqp://..?heartbeat=0 should end up with heartbeat=0 on both client & in rabbitmq web ui.

unexpected behaviour

Actually, amqp://..?heartbeat=0 does not end up with a configured HB=0, but only inherits whatever the server has recommended.

In addition, despite the wire protocol negotiation being correct, the actual heartbeats are not sent at the expected 1/2 heartbeat time, (presumably as the requested 0 HB setting is propagated into rabbitmq-common's heartbeat timer on the server side, even though this doesn't match what has been agreed on the wire).

Thus, from the client's perspective, after the server has not sent any heartbeats, the gen_server hits a timeout, and the erlang client then cleans up, requesting to close the TCP connection and the server responds in kind.

possible bug

https://github.com/rabbitmq/rabbitmq-erlang-client/blob/master/src/amqp_network_connection.erl#L236-L243 looks like it makes incorrect comparisons in this specific case:

    [ChannelMax, Heartbeat, FrameMax] =
        lists:zipwith(fun (Client, Server) when Client =:= 0; Server =:= 0 ->
                              lists:max([Client, Server]);
                          (Client, Server) ->
                              lists:min([Client, Server])
                      end,
                      [ClientChannelMax, ClientHeartbeat, ClientFrameMax],
[ServerChannelMax, ServerHeartbeat, ServerFrameMax]),
3> [ClientChannelMax, ClientHeartbeat, ClientFrameMax] = [0,0,0].
[0,0,0]
4> [ServerChannelMax, ServerHeartbeat, ServerFrameMax] = [0,10,0].
[0,10,0]
5> lists:zipwith(fun (Client, Server) when Client =:= 0; Server =:= 0 ->
5>                               lists:max([Client, Server]);
5>                           (Client, Server) ->
5>                               lists:min([Client, Server])
5>                       end,
5>                       [ClientChannelMax, ClientHeartbeat, ClientFrameMax],
5> [ServerChannelMax, ServerHeartbeat, ServerFrameMax]).
[0,10,0]

I think we should see [0,0,0] here, for example.

speculation

As mentioned above, I think this is therefore wrong on both server and client for RabbitMQ as the library is shared in both systems. In addition, I think this incorrect setting propagates further, into rabbit_common:start_timer, causing the negotiated AMQP heartbeats (which we didn't request!) not to be send from the server (as the amqp params has heartbeat=0 which doesn't match what is agreed on the wire, as confirmed by tcpdump), but the client is still expecting to receive a heartbeat, and when it doesn't receive one, the TCP connection is reset, which causes the entire connection to fail. I think this hits codepath here https://github.com/rabbitmq/rabbitmq-common/blob/master/src/rabbit_heartbeat.erl#L109-L113 with the 0 pattern match.

This ultimately causes the client to send a FIN/ACK requesting to close the channel as the connection has not received the expected heartbeats from the server -- this is the "matching bug" on the server end causing problems, I think.

Anyway, I have a tcpdump that I can share privately if needed, email/irc is fine, but it's easy enough to reproduce as follows:

test setup

  • git clone this repo and gmake deps app shell
application:ensure_all_started(lager).
application:ensure_all_started(amqp_client).
{ok, Params} = amqp_uri:parse("amqp://localhost?heartbeat=0").
{ok, Conn} = amqp_connection:start(Params, <<"hb_0">>).
{ok, Chan} = amqp_connection:open_channel(Conn).
amqp_connection:info(Conn,  [heartbeat]).

tcpdump of succesful tune negotiation

Advanced Message Queueing Protocol
    Type: Method (1)
    Channel: 0
    Length: 12
    Class: Connection (10)
    Method: Tune-Ok (31)
    Arguments
        Channel-Max: 200
        Frame-Max: 16384
        Heartbeat: 120

tcpdump of final RST conversation at end of stream

client->server

Frame 16: 66 bytes on wire (528 bits), 66 bytes captured (528 bits)
Ethernet II, Src: SuperMic_67:e1:38 (ac:1f:6b:67:e1:38), Dst: LannerEl_4d:67:99 (00:90:0b:4d:67:99)
Internet Protocol Version 4, Src: 172.16.1.14 (172.16.1.14), Dst: 35.205.27.21 (35.205.27.21)
Transmission Control Protocol, Src Port: 36664, Dst Port: 5672, Seq: 519, Ack: 539, Len: 0
    Source Port: 36664
    Destination Port: 5672
    <Source or Destination Port: 36664>
    <Source or Destination Port: 5672>
    [Stream index: 0]
    [TCP Segment Len: 0]
    Sequence number: 519    (relative sequence number)
    [Next sequence number: 519    (relative sequence number)]
    Acknowledgment number: 539    (relative ack number)
    1000 .... = Header Length: 32 bytes (8)
    Flags: 0x011 (FIN, ACK)
        000. .... .... = Reserved: Not set
        ...0 .... .... = Nonce: Not set
        .... 0... .... = Congestion Window Reduced (CWR): Not set
        .... .0.. .... = ECN-Echo: Not set
        .... ..0. .... = Urgent: Not set
        .... ...1 .... = Acknowledgment: Set
        .... .... 0... = Push: Not set
        .... .... .0.. = Reset: Not set
        .... .... ..0. = Syn: Not set
        .... .... ...1 = Fin: Set
        [TCP Flags: ·······A···F]
    Window size value: 8192
    [Calculated window size: 4194304]
    [Window size scaling factor: 512]
    Checksum: 0xec26 [unverified]
    [Checksum Status: Unverified]
    Urgent pointer: 0
    Options: (12 bytes), No-Operation (NOP), No-Operation (NOP), Timestamps
        TCP Option - No-Operation (NOP)
            Kind: No-Operation (1)
        TCP Option - No-Operation (NOP)
            Kind: No-Operation (1)
        TCP Option - Timestamps: TSval 103686017, TSecr 998118205
            Kind: Time Stamp Option (8)
            Length: 10
            Timestamp value: 103686017
            Timestamp echo reply: 998118205
    [Timestamps]
        [Time since first frame in this TCP stream: 60.228733000 seconds]
        [Time since previous frame in this TCP stream: 59.915805000 seconds]

server->client

Frame 17: 66 bytes on wire (528 bits), 66 bytes captured (528 bits)
Ethernet II, Src: LannerEl_4d:67:99 (00:90:0b:4d:67:99), Dst: SuperMic_67:e1:38 (ac:1f:6b:67:e1:38)
Internet Protocol Version 4, Src: 35.205.27.21 (35.205.27.21), Dst: 172.16.1.14 (172.16.1.14)
Transmission Control Protocol, Src Port: 5672, Dst Port: 36664, Seq: 539, Ack: 520, Len: 0
    Source Port: 5672
    Destination Port: 36664
    <Source or Destination Port: 5672>
    <Source or Destination Port: 36664>
    [Stream index: 0]
    [TCP Segment Len: 0]
    Sequence number: 539    (relative sequence number)
    [Next sequence number: 539    (relative sequence number)]
    Acknowledgment number: 520    (relative ack number)
    1000 .... = Header Length: 32 bytes (8)
    Flags: 0x014 (RST, ACK)
        000. .... .... = Reserved: Not set
        ...0 .... .... = Nonce: Not set
        .... 0... .... = Congestion Window Reduced (CWR): Not set
        .... .0.. .... = ECN-Echo: Not set
        .... ..0. .... = Urgent: Not set
        .... ...1 .... = Acknowledgment: Set
        .... .... 0... = Push: Not set
        .... .... .1.. = Reset: Set
        .... .... ..0. = Syn: Not set
        .... .... ...0 = Fin: Not set
        [TCP Flags: ·······A·R··]
    Window size value: 2816
    [Calculated window size: 2816]
    [Window size scaling factor: 1]
    Checksum: 0xc02a [unverified]
    [Checksum Status: Unverified]
    Urgent pointer: 0
    Options: (12 bytes), No-Operation (NOP), No-Operation (NOP), Timestamps
        TCP Option - No-Operation (NOP)
            Kind: No-Operation (1)
        TCP Option - No-Operation (NOP)
            Kind: No-Operation (1)
        TCP Option - Timestamps: TSval 998133217, TSecr 103686017
            Kind: Time Stamp Option (8)
            Length: 10
            Timestamp value: 998133217
            Timestamp echo reply: 103686017
    [SEQ/ACK analysis]
    [Timestamps]
        [Time since first frame in this TCP stream: 60.261940000 seconds]
        [Time since previous frame in this TCP stream: 0.033207000 seconds]

erlang shell session showing bug and timeout

These are logs from client side of reproduced issue (with connection loss after 60s as cloudamqp has a 120s heartbeat default).

rabbitmq-erlang-client> gmake deps app shell
gmake[1]: Entering directory '/repos/rabbitmq-erlang-client/deps/rabbit_common'
gmake[2]: Entering directory '/repos/rabbitmq-erlang-client/deps/rabbitmq_codegen'
gmake[2]: Leaving directory '/repos/rabbitmq-erlang-client/deps/rabbitmq_codegen'
gmake[2]: Entering directory '/repos/rabbitmq-erlang-client/deps/lager'
gmake[3]: Entering directory '/repos/rabbitmq-erlang-client/deps/goldrush'
gmake[3]: Leaving directory '/repos/rabbitmq-erlang-client/deps/goldrush'
 DEPEND lager.d
gmake[2]: Leaving directory '/repos/rabbitmq-erlang-client/deps/lager'
gmake[2]: Entering directory '/repos/rabbitmq-erlang-client/deps/jsx'
gmake[2]: Leaving directory '/repos/rabbitmq-erlang-client/deps/jsx'
gmake[2]: Entering directory '/repos/rabbitmq-erlang-client/deps/ranch'
gmake[2]: Leaving directory '/repos/rabbitmq-erlang-client/deps/ranch'
gmake[2]: Entering directory '/repos/rabbitmq-erlang-client/deps/ranch_proxy_protocol'
gmake[2]: Leaving directory '/repos/rabbitmq-erlang-client/deps/ranch_proxy_protocol'
gmake[2]: Entering directory '/repos/rabbitmq-erlang-client/deps/recon'
gmake[2]: Leaving directory '/repos/rabbitmq-erlang-client/deps/recon'
gmake[1]: Leaving directory '/repos/rabbitmq-erlang-client/deps/rabbit_common'
 DEPEND amqp_client.d
 GEN    shell
Erlang/OTP 21 [erts-10.1.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe] [dtrace]
Eshell V10.1.1  (abort with ^G)
1> application:ensure_all_started(lager), application:ensure_all_started(amqp_client), f(), {ok, Params} = amqp_uri:parse("amqp://...?heartbeat=0"), logger:warning("STARTING NOW"), {ok, Conn} = amqp_connection:start(Params, <<"hb_0">>), {ok, Chan} = amqp_connection:open_channel(Conn), amqp_connection:info(Conn,  [heartbeat]).

=WARNING REPORT==== 19-Nov-2018::00:29:12.837544 ===
STARTING NOW
[{heartbeat,120}]
2> =ERROR REPORT==== 19-Nov-2018::00:30:13.054977 ===
** Generic server <0.154.0> terminating 
** Last message in was {inet_async,#Port<0.6>,5,{error,timeout}}
** When Server state == {state,#Port<0.6>,<0.148.0>,<0.152.0>,
                               {method,rabbit_framing_amqp_0_9_1},
                               {expecting_header,<<>>}}
** Reason for termination == 
** {socket_error,timeout}

=ERROR REPORT==== 19-Nov-2018::00:30:13.055066 ===
** Generic server <0.148.0> terminating 
** Last message in was {socket_error,timeout}
** When Server state == {state,amqp_network_connection,
                            {state,#Port<0.6>,
                                <<"client 172.16.1.14:37471 -> 35.205.27.21:5672">>,
                                120,<0.153.0>,16384,<0.147.0>,undefined,false},
                            <0.152.0>,
                            {amqp_params_network,<<"...">>,
                                <<"...">>,
                                <<"...">>,"....cloudamqp.com",5672,
                                2047,0,0,60000,none,
                                [#Fun<amqp_uri.12.131604370>,
                                 #Fun<amqp_uri.12.131604370>],
                                [{<<"connection_name">>,longstr,<<"hb_0">>}],
                                []},
                            200,
                            [{<<"capabilities">>,table,
                              [{<<"publisher_confirms">>,bool,true},
                               {<<"exchange_exchange_bindings">>,bool,true},
                               {<<"basic.nack">>,bool,true},
                               {<<"consumer_cancel_notify">>,bool,true},
                               {<<"connection.blocked">>,bool,true},
                               {<<"consumer_priorities">>,bool,true},
                               {<<"authentication_failure_close">>,bool,true},
                               {<<"per_consumer_qos">>,bool,true},
                               {<<"direct_reply_to">>,bool,true}]},
                             {<<"cluster_name">>,longstr,<<"...">>},
                             {<<"copyright">>,longstr,
                              <<"Copyright (C) 2007-2018 Pivotal Software, Inc.">>},
                             {<<"information">>,longstr,
                              <<"Licensed under the MPL.  See http://www.rabbitmq.com/">>},
                             {<<"platform">>,longstr,
                              <<"Erlang/OTP 20.3.8.7">>},
                             {<<"product">>,longstr,<<"RabbitMQ">>},
                             {<<"version">>,longstr,<<"3.6.16">>}],
                            none,false}
** Reason for termination == 
** {socket_error,timeout}

=CRASH REPORT==== 19-Nov-2018::00:30:13.055693 ===
  crasher:
    initial call: amqp_main_reader:init/1
    pid: <0.154.0>
    registered_name: []
    exception exit: {socket_error,timeout}
      in function  gen_server:handle_common_reply/8 (gen_server.erl, line 751)
    ancestors: [<0.147.0>,<0.146.0>,amqp_sup,<0.144.0>] 
    message_queue_len: 0
    messages: []
    links: [<0.147.0>]
    dictionary: [{process_name,
                      {amqp_main_reader,
                          <<"client 172.16.1.14:37471 -> 35.205.27.21:5672">>}},
                  {gen_server_call_timeout,60000}]  ***********************************************************************
    trap_exit: false
    status: running
    heap_size: 1598
    stack_size: 27
    reductions: 10297
  neighbours:

=CRASH REPORT==== 19-Nov-2018::00:30:13.059347 ===
  crasher:
    initial call: amqp_gen_connection:init/1
    pid: <0.148.0>
    registered_name: []
    exception exit: {socket_error,timeout}
      in function  gen_server:handle_common_reply/8 (gen_server.erl, line 751)
    ancestors: [<0.146.0>,amqp_sup,<0.144.0>]
    message_queue_len: 0
    messages: []
    links: [<0.146.0>,#Port<0.6>]
    dictionary: [{process_name,
                      {amqp_gen_connection,
                          <<"client 172.16.1.14:37471 -> 35.205.27.21:5672">>}},
                  {gen_server_call_timeout,60000}]
    trap_exit: true
    status: running
    heap_size: 6772
    stack_size: 27
    reductions: 211709
  neighbours:

00:30:13.060 [error] gen_server <0.154.0> terminated with reason: {socket_error,timeout}
00:30:13.060 [error] gen_server <0.148.0> terminated with reason: {socket_error,timeout}
00:30:13.060 [error] CRASH REPORT Process <0.154.0> with 0 neighbours exited with reason: {socket_error,timeout} in gen_server:handle_common_reply/8 line 751
00:30:13.060 [error] CRASH REPORT Process <0.148.0> with 0 neighbours exited with reason: {socket_error,timeout} in gen_server:handle_common_reply/8 line 751
00:30:13.065 [error] Supervisor {<0.147.0>,amqp_connection_type_sup} had child main_reader started with amqp_main_reader:start_link(#Port<0.6>, <0.148.0>, <0.152.0>, {method,rabbit_framing_amqp_0_9_1}, <<"client 172.16.1.14:37471 -> 35.205.27.21:5672">>) at <0.154.0> exit with reason {socket_error,timeout} in context child_terminated
00:30:13.065 [error] Supervisor {<0.147.0>,amqp_connection_type_sup} had child main_reader started with amqp_main_reader:start_link(#Port<0.6>, <0.148.0>, <0.152.0>, {method,rabbit_framing_amqp_0_9_1}, <<"client 172.16.1.14:37471 -> 35.205.27.21:5672">>) at <0.154.0> exit with reason reached_max_restart_intensity in context shutdown
00:30:13.066 [error] Supervisor {<0.146.0>,amqp_connection_sup} had child connection started with amqp_gen_connection:start_link(<0.147.0>, {amqp_params_network,<<"hvvnfues">>,<<"722qGIKqIvvTfGa--Zj23Lq1_fpy50w7">>,<<"hvvnfues">>,"sheep...",...}) at <0.148.0> exit with reason {socket_error,timeout} in context child_terminated
00:30:13.067 [error] Supervisor {<0.146.0>,amqp_connection_sup} had child connection started with amqp_gen_connection:start_link(<0.147.0>, {amqp_params_network,<<"hvvnfues">>,<<"722qGIKqIvvTfGa--Zj23Lq1_fpy50w7">>,<<"hvvnfues">>,"sheep...",...}) at <0.148.0> exit with reason reached_max_restart_intensity in context shutdown

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.