Tcp connection issue: Assertion failed, no matching message after 2000ms

Actually i am implement a raft in elixir, and i am working on tcp_transport now ,
these are my files

but i am getting this error when i am running tests

 1) test basic TCP transport can connect and send messages bi-directionally (ElixirRaft.Network.TcpTransportTest)
     test/elixir_raft/network/tcp_transport_test.exs:51
     Assertion failed, no matching message after 2000ms
     The following variables were pinned:
       node2_id = "node_2_38"
     Showing 1 of 1 message in the mailbox
     code: assert_receive {:received_t1, ^node2_id, "hello"}
     mailbox:
       pattern: {:received_t1, ^node2_id, "hello"}
       value:   {:received_t2, "node_1_38", "world"}
     stacktrace:
       test/elixir_raft/network/tcp_transport_test.exs:101: (test)

     The following output was logged:
     
     20:36:50.514 [info] TCP Transport listening on port 35581
     
     20:36:50.615 [debug] Attempting to connect to node_1_38 at {0, 0, 0, 0}:35581
     
     20:36:50.616 [info] Processing inbound connection from node_2_38
     
     20:36:50.616 [info] Successfully established bi-directional connection to node_1_38
     
     20:36:50.616 [debug] Connection status - T1->T2: connected, T2->T1: connected
     
     20:36:50.717 [debug] Sending message from T2 to T1
     
     20:36:50.717 [debug] Successfully sent message to node_1_38
     
     20:36:50.768 [debug] Sending message from T1 to T2
     
     20:36:50.768 [debug] Successfully sent message to node_2_38
     
     20:36:50.770 [debug] T2 received message from node_1_38: "world"
     
....
Finished in 2.3 seconds (2.3s async, 0.00s sync)
9 tests, 1 failure

the message is sending from t1 to t2, but not t2 to t1, can anyone explain me why the root cause is , i am not getting trying from past 4 hrs.

I wonder if the messages are being delivered to your acceptor process. The destination process for messages can be changed with :gen_tcp.controlling_process/2

1 Like

but one process is receiving the data, but other process is not receiving, that’s where i am stuck, i am sending through the same connection

Your server uses a new acceptor process (via a spawn_link/1 in start_acceptor/2). This process is accepting the socket request from the client, and presumably handle_new_connection/2 is working as expected for you?

If so, try adding a call to :gen_tcp.controlling_process/2 in this location:

        case send_message(socket, encode_handshake(our_node_id)) do
          :ok ->
            :gen_tcp.controlling_process(socket, parent) # <-- try adding this
            GenServer.cast(parent, {:inbound_connection, socket, remote_node_id})
            {:ok, remote_node_id}
          error ->
            Logger.error("Failed to complete handshake: #{inspect(error)}")
            :gen_tcp.close(socket)
            error
        end

This should transfer responsibility of the socket to the GenServer, and allow that GenServer process to receive the messages.

This differs from your TCP client-side implementation (at least I think so, I did not read in great detail), which connects and receives messages in the same process, so a change in the controlling process is not required.

2 Likes

+1 for needing the call to :gen_tcp.controlling_process - I tried it, and the test passes with it added.

1 Like

can you just share the snippets

It’s worked, thanks for the help.

1 Like