mingchaoyan
mingchaoyan

Reputation: 8616

which case we should use The Hybrid Approach Socket in Erlang?

Programing Erlang says in chapter 17.2

Erlang sockets can be opened in one of three modes: active, active once, or passive

...

You might think that using passive mode for all servers is the correct approach. Unfortunately, when we’re in passive mode, we can wait for the data from only one socket. This is useless for writing servers that must wait for data from multiple sockets.

I just could not understand the sentence This is useless for writing servers that must wait for data from multiple sockets

In my opinion, if I can not convince the clients, I should not use the active mode.

But I can make a Parallel Server with passive mode for each client(one Erlng process for one client).

Maybe it says that a Erlang process for multiple sockets. But I can not imagine the example of this case.

Could you give me more information about it?

Thank you!

Upvotes: 2

Views: 81

Answers (1)

legoscia
legoscia

Reputation: 41648

Unfortunately, when we’re in passive mode, we can wait for the data from only one socket. This is useless for writing servers that must wait for data from multiple sockets.

I'd say that's not a very compelling argument against passive sockets. In almost all cases, you'll have one Erlang process per socket, and this problem doesn't arise.

A better argument against passive sockets is that while waiting for data (using gen_tcp:recv), the process cannot receive messages from other Erlang processes. Those messages could be the result of a computation, a request to shut down, etc.

That is, when using active or active-once mode, your receive would look something like this:

receive
    {tcp, Socket, Data} ->
        %% do something with Data
        %% then reactivate the socket
        ok = inet:setopts(Socket, [{active,once}]),
        loop(Socket);
    {result, Result} ->
        %% send Result back to socket
        ok = gen_tcp:send(Socket, Result),
        loop(Socket);
    stop ->
        %% stop this process
        exit(normal)
end

Using this code, whichever event arrives first will be handled first, regardless of whether it's incoming data on the socket or a message from another Erlang process.

If on the other hand you were using gen_tcp:recv to receive the data, you would block on that call, unable to react to {result, Result} and stop in a timely manner.

Upvotes: 4

Related Questions