Search code examples
erlangsenddistributeddistributed-systemreceiver

Erlang can not receive message from where it begins


There are two files here.

temp_converter() ->
receive
    {convertToCelsius, {From, TempF}} ->
        io:format("Temp-Server2 > Converter received message from ~w~n", [From]),
        ConvertedTempC = (TempF-32)*5/9,
        From ! finished,
        From ! {converted, ConvertedTempC},
        temp_converter();
    {From, {convertToCelsius, TempF}} ->
        io:format("Temp-Server > Converter received message from ~w~n", [From]),
        ConvertedTempC = (TempF-32)*5/9,
        From ! {converted, ConvertedTempC},
        temp_converter()
end.

The other one is:

sensor(Temp, Temp_Node, Dis_Node) ->
receive
    finished ->
        io:foramt("finished");
    % Receive the clock_tick from clock controller
    clock_tick ->
        io:format("Sensor_f received tick~n", []),
        {temp_converter, Temp_Node} ! {convertToCelsius, {self(), Temp}};
    % Receive the temperature which has been converted
    {converted, ConvertedTemp} ->
        io:format("Sensor_f received converted temperature~n", []),
        {display_module, Dis_Node} ! {inCelsius, ConvertedTemp};
    {'EXIT', From, Reason} ->
        io:foramt("Temperature Server down!~nGot ~p~n", [{'EXIT', From, Reason}])
end.

Basically, the sensor will send message to temp_converter, which is implemented in "clock_tick ->". When temp_converter received message, it will output something and send message back. Here is the problem. It does output something, but sensor can not receive message from temp_converter. Is there anything wrong with my code? I also tried to send "finished" message back, but it still does not work!!

How can I send message back? How can I change "From ! finished" and "From ! {converted, ConvertedTempC}," to be correct?


Solution

  • In the conversion:

    {convertToCelsius, {From, TempF}} ->
        io:format("Temp-Server2 > Converter received message from ~w~n", [From]),
        ConvertedTempC = (TempF-32)*5/9,
        From ! finished, %% Here you send to sensor the message 'finished'
        From ! {converted, ConvertedTempC}, %% the conversion will be received                                    %% after the first message (guaranteed by Erlang VM)
        temp_converter();
    

    And in the sensor:

    finished ->
        io:foramt("finished"); %% when you receive the first message, you print it
                               %% and leave the function. The next message will be lost
                               %% because you do not loop in the sensor function.
    

    you only have to recall sensor(Temp, Temp_Node, Dis_Node) after the receive bloc and it should be fine.

    Note that the message finished is useless in your case and that a simple call to a conversion function should do the job.