[erlang-questions] How about the net IO ability of erlang

leon zhao realaqura@REDACTED
Wed Sep 10 11:16:31 CEST 2008


I worte a tcp proxy to forward data from peer to peer, but i find the CPU
usage of beam is high in test
The client make 1000 connections per second and get 16K data from
server, and the server send 8K to client per second, because we want to
decrease the traffic.
And the compute's CPU is Intel(R) Xeon(TM) CPU 3.20GHz, so the proxy's usage
is on avenage 26%
Is my codes have some problem or erlang need some optimization.
Anyone can tell me

here is my codes

%%%----------------------------------------------------------------------
%%% File    : tcp.erl
%%% Author  : Zhao Liang<realaqura@REDACTED>
%%%----------------------------------------------------------------------
-module(tcp).
-author('realaqura@REDACTED').
-compile(export_all).

-define(MAIN_MODULE,  tcp).

-record(cfg, {
 listen_port = 10080,
 idle = 30000}).

main(Port) ->
    Cfg = #cfg{listen_port=Port},
    case gen_tcp:listen(Port, [{reuseaddr,true}, {active,false},
{backlog,64}, binary]) of
        {ok, LSock} ->
            create_accept_thread(LSock, Cfg, self()),
            tcp_ctl_loop(LSock, Cfg, self());
        ERR -> ERR
    end.
tcp_ctl_loop(LSock, Cfg, Self) ->
    receive
    {_, next} ->
        create_accept_thread(LSock, Cfg, Self),
        tcp_ctl_loop(LSock, Cfg, Self);
    _ ->
        tcp_ctl_loop(LSock, Cfg, Self)
    end.
create_accept_thread(LSock, Cfg, Pid) ->
    spawn_link(?MAIN_MODULE, accept_thread, [LSock, Cfg, Pid]).
accept_thread(LSock, Cfg, Parent) ->
    accept_loop(LSock, Cfg, Parent).
accept_loop(LSock, Cfg, Parent) ->
    case prim_inet:async_accept(LSock, -1) of
        {ok, Ref} ->
            receive
                {inet_async, LSock, Ref, {ok,CSock}} ->
                    Parent ! {self(), next},
                    tcp_start(CSock, Cfg);
                {inet_async, LSock, Ref, _} ->
                    accept_loop(LSock, Cfg, Parent)
            end;
        _ ->
            accept_loop(LSock, Cfg, Parent)
    end.
tcp_start(CSock, Cfg) ->
    case prim_inet:getopts(CSock, [original_dst]) of
        {ok, [{original_dst, {Oport, Oip}}]} ->
            case gen_tcp:connect(Oip, Oport, [{active,true}, {packet,raw},
binary], Cfg#cfg.idle) of
                {ok, SSock} ->
                    tcp_start(CSock, SSock, Cfg);
                _ ->
                    inet:tcp_close(CSock)
            end;
        _ ->
            inet:tcp_close(CSock)
    end.
tcp_start(CSock, SSock, Cfg) ->
    inet:setopts(CSock, [{active, true}, {packet,raw}, binary]),
    tcp_data_loop(CSock, SSock, Cfg).
tcp_data_loop(CSock, SSock, Cfg) ->
    receive
        {tcp, Socket, Data} ->
            if
                Socket == CSock ->
                    case prim_inet:send(SSock, Data) of
                        ok ->
                            tcp_data_loop(CSock, SSock, Cfg);
                        _ ->
                            gen_tcp:close(CSock),
                            gen_tcp:close(SSock)
                    end;
                Socket == SSock ->
                    case prim_inet:send(CSock, Data) of
                        ok ->
                            tcp_data_loop(CSock, SSock, Cfg);
                        _ ->
                            gen_tcp:close(CSock),
                            gen_tcp:close(SSock)
                    end;
                true ->
                    tcp_data_loop(CSock, SSock, Cfg)
            end;
        {tcp_closed, Socket} ->
            if
                Socket == CSock ->
                    gen_tcp:close(SSock);
                Socket == SSock ->
                    gen_tcp:close(CSock);
                true ->
                    gen_tcp:close(CSock),
                    gen_tcp:close(SSock)
            end;
         _ ->
            gen_tcp:close(CSock),
            gen_tcp:close(SSock)
    after
        Cfg#cfg.idle ->
            gen_tcp:close(CSock),
            gen_tcp:close(SSock)
    end.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20080910/fe0d03da/attachment.htm>


More information about the erlang-questions mailing list