[erlang-questions] Questions about lib_chan and IRC Lite (other than the one had been asked before).

lang qiu <>
Wed Jan 14 16:27:27 CET 2009


First of all, thanks for answering my question!

But the solution you provided does not solve the problem completely. Because
the main problem here is that if a process sends several messages in a row,
then the receiving process may fail to process them correctly. Your solution
can only solve the problem if the process only send *2* *messages *in a row,

   receive
   {connected, Connector, MM} ->
        lib_chan_mm:send(MM, {login, Group, Nick}),
       * receive {'EXIT', Connector, connectorFinished} -> ok end,*
       %% *can only take 1 more message *here even if you add more receiving
match  pattern,
       %% the remaining message still goes into wait_login_response/2
       wait_login_response(Widget, MM);

For example if try_to_connect/4 sends 3 messages to parent,

try_to_connect(Parent, Host, Port, Pwd) ->
        ...
        Parent ! {connected, self(), MM},
        Parent ! {hello, self(), MM),
        exit(*connectorFinished*)
    end.

The parent still fails to process them even with your solution,

disconnected(Widget, Group, Nick) ->
    receive
    {connected, Connector, MM} ->
           receive
            {hello, _ }  -> io:format("hello in connected~n");
            // The following clause won't work!
            {'EXIT', _Connector, connectorFinished} -> io:format("connect
finished ~n")
         end,
        lib_chan_mm:send(MM, {login, Group, Nick}),
        wait_login_response(Widget, MM);

Because the added receive codes can only take 1 more message, the remaining
messages still goes in to wait_login_response(Widget, MM);

So I still think we should make the outer receive codes process the message
instead of letting one of matching section (connected here) process the
remaining message. But is that possible ?

Thanks!

PS maybe you need to see the whole source code so I attach it here.

try_to_connect(Parent, Host, Port, Pwd) ->
    case lib_chan:connect(Host, Port, chat, Pwd, []) of
    {error, _Why} ->
        Parent ! {status, {cannot, connect, Host, Port}},
        sleep(2000),
        try_to_connect(Parent, Host, Port, Pwd);
    {ok, MM} ->
        lib_chan_mm:controller(MM, Parent),
        *Parent ! {connected, MM},*
        Parent ! hello,
        exit(connectorFinished)
    end.

disconnected(Widget, Group, Nick) ->
    receive
    {connected, MM} ->
        insert_str(Widget, "connected to server\nsending data\n"),
           receive
            hello -> io:format("hello in connected~n");
            {'EXIT', _Connector, connectorFinished} -> io:format("connect
finished ~n")
         end,
        lib_chan_mm:send(MM, {login, Group, Nick}),
        wait_login_response(Widget, MM);
    {Widget, destroyed} ->
        exit(died);
    {status, S} ->
        insert_str(Widget, to_str(S)),
        disconnected(Widget, Group, Nick);
    Other ->
        io:format("chat_client disconnected unexpected:~p~n",[Other]),
        disconnected(Widget, Group, Nick)
    end.

wait_login_response(Widget, MM) ->
    receive
    {chan, MM, ack} ->
        io:format("I am login~n"),
        active(Widget, MM);
    Other ->
        io:format("chat_client login unexpected:~p~n",[Other]),
        wait_login_response(Widget, MM)
    end.


On Wed, Jan 14, 2009 at 6:20 PM, Gleb Peregud <> wrote:

> 2009/1/14 lang qiu <>:
> > Hi all,
> >
> > Nobody replies my question about IRC Lite, so I ask it the second time
> > (Change the title in hoping that it may cause some attention). And I
> notice
> > that someone asked about some other questions about IRC Lite before,
> which
> > may suggest this example is tricky.
> >
> > So my here is my question, if a process sends another process several
> > messages in a row while in the receiving process when it processes the
> first
> > message, it does that in its own receiving loop, then all the remaining
> > message the first process sends goes into this loop and this may against
> the
> > purpose.
> >
> > My words may sound nonsense. So check these codes,
> >
> > In the chat_client.erl,
> >
> > try_to_connect(Parent, Host, Port, Pwd) ->
> >         ...
> >         Parent ! {connected, MM},
> >         exit(connectorFinished)
> >     end.
> >
> > While in parent disconnected/3,
> > ...
> >     receive
> >     {connected, MM} ->
> >         lib_chan_mm:send(MM, {login, Group, Nick}),
> >         wait_login_response(Widget, MM);
> >      {'EXIT', _Pid, _Reason} -> %% if we add this clause here
> > ...
> > wait_login_response/2 defines,
> > ...
> >      receive
> >      ...
> >      Other ->
> >         io:format("chat_client login unexpected:~p~p~n",[Other,MM]),
> > ...
> >
> > The result shows that wait_login_response/2 receives try_to_connect's
> 'EXIT'
> > message not disconnected/3. I further test that if try_to_connect sends
> more
> > messages after {connected, MM} , they will all be received by
> > wait_login_response instead of disconnected/3 even there are match
> patterns
> > in disconnected/3 (Correct me if I am wrong). But this may not be a good
> > idea. Maybe it is better to let disconnected/3 processes the 'EXIT'
> message
> > instead of wait_login_response/2 (because it should only deal with the
> login
> > related message). So how do we fix this problem ?  Or I miss something
> here
> > ?
> >
> > Thanks,
> >
> > Qiulang
> >
> > _______________________________________________
> > erlang-questions mailing list
> > 
> > http://www.erlang.org/mailman/listinfo/erlang-questions
> >
>
>
>
> You can try alter the code in the following way:
>
> try_to_connect(Parent, Host, Port, Pwd) ->
>        ...
>         Parent ! {connected, self(), MM},
>         exit(connectorFinished)
>    end.
>
> While in parent disconnected/3,
> ...
>    receive
>     {connected, Connector, MM} ->
>         lib_chan_mm:send(MM, {login, Group, Nick}),
>         receive {'EXIT', Connector, connectorFinished} -> ok end,
>         wait_login_response(Widget, MM);
>     {'EXIT', _Pid, _Reason} -> %% if we add this clause here
> ...
> wait_login_response/2 defines,
> ...
>     receive
>     ...
>     Other ->
>        io:format("chat_client login unexpected:~p~p~n",[Other,MM]),
> ...
>
> This change makes parent:disconnected/3 catch 'EXIT' message of
> connector at the appropriate moment. Note: I don't know what remaining
> code looks like, hence this is based solely on code in your email.
>
> --
> Gleb Peregud
> http://gleber.pl/
>
> Every minute is to be grasped.
> Time waits for nobody.
> -- Inscription on a Zen Gong
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20090114/a4aea97c/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: chat_client.erl
Type: application/octet-stream
Size: 3772 bytes
Desc: not available
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20090114/a4aea97c/attachment.obj>


More information about the erlang-questions mailing list