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
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.