Ranch Source Code Analysis (iii)

Source: Internet
Author: User

Access to Ranch source Analysis (ii)

Last time we talked about the core modules of the 2 ranch Ranch_conns_sup and Ranch_acceptors_sup, we went on to analyze

First View Ranch_conns_sup.erl

-Module(ranch_conns_sup).%%API.-Export([START_LINK/6]).-Export([START_PROTOCOL/2]).-Export([ACTIVE_CONNECTIONS/1]).%...... Omit several lines%%API.-spec Start_link (Ranch:ref (), Conn_type (), Shutdown (),Module(), timeout (),Module()){OK, pid ()}.start_link (Ref, Conntype, Shutdown, Transport, AckTimeout, Protocol)-Proc_lib:start_link (?MODULE, Init, [self (), Ref, Conntype, Shutdown, Transport, AckTimeout, Protocol]).%...... Omit several lines%%Supervisor Internals.-spec Init (PID (), Ranch:ref (), Conn_type (), Shutdown (),Module(), timeout (),Module())No_return (). Init (Parent, Ref, Conntype, Shutdown, Transport, AckTimeout, Protocol)-Process_flag (Trap_exit,true), OK=Ranch_server:set_connections_sup (Ref, Self ()), Maxconns=ranch_server:get_max_connections (REF), Opts=ranch_server:get_protocol_options (Ref), OK=Proc_lib:init_ack (parent, {OK, self ()}), Loop (#state {parent=parent, Ref=ref, conn_type=Conntype, Shutdown=shutdown, Transport=transport, protocol=Protocol, opts=opts, Ack_timeout=acktimeout, Max_conns=maxconns}, 0, 0, []). Loop ( State= #state {parent=parent, ref=ref, conn_type=Conntype, Transport=transport, Protocol=protocol, opts=Opts, Max_conns=maxconns}, Curconns, Nbchildren, sleepers)Receive        {? MODULE, Start_protocol, to, Socket},TryProtocol:start_link (Ref, Socket, Transport, Opts) of{OK, Pid}-shoot (state, Curconns, Nbchildren, sleepers, to, Socket, PID, PID); {OK, suppid, protocolpid} whenConntype =:= Supervisorshoot (state, Curconns, Nbchildren, sleepers, to, Socket, Suppid, protocolpid);%...... Omit several lines shoot( state= #state {ref=ref, Transport=transport, Ack_timeout=acktimeout, max_conns=Maxconns}, Curconns, Nbchildren, sleepers, to, Socket, Suppid, Protocolpid)- CaseTransport:controlling_process (Socket, Protocolpid) ofOK-Protocolpid!{shoot, Ref, Transport, Socket, acktimeout}, put (Suppid,true), CurConns2= Curconns + 1,            ifCurConns2 < Maxconns to!Self (), Loop (state, CURCONNS2, Nbchildren+ 1, sleepers); true-Loop (state, CURCONNS2, Nbchildren+ 1, [to|Sleepers]) End; {error, _}-Transport:close (Socket),%%Only kill the supervised PID, because the connection ' s PID,            %%When different, was supposed to be sitting under it and linked.exit (Suppid, Kill), loop (state, Curconns, Nbchildren, sleepers)End.%...... Omit several lines

You can see that ranch_conns_sup is not a typical gen_tcp module,

Start_link the loop is used directly after starting INIT,

The Init function mainly obtains some parameters,

Loop waits for a message ( we mainly look at the Start_protocol message ), and the loop function launches the Protocol:start_link based on the START_PROTOCOL message (the user-written application module, which represents Echo_ Protocol), pay attention to who sent the message to him later .

When you start the normal, record the Protocolpid

Continue to view Ranch_acceptors_sup.erl

-Module(ranch_acceptors_sup).-behaviour (supervisor).-Export([START_LINK/4]).-Export([INIT/1]).-spec Start_link (Ranch:ref (), Non_neg_integer (),Module(), any ())-{OK, pid ()}. Start_link (Ref, Nbacceptors, Transport, transopts)-Supervisor:start_link (?MODULE, [Ref, Nbacceptors, Transport, transopts]). Init ([Ref, Nbacceptors, Transport, transopts])-Connssup=Ranch_server:get_connections_sup (REF), Lsocket= CaseProplists:get_value (socket, transopts) ofundefined-TransOpts2=Proplists:delete (Ack_timeout, Proplists:delete (Connection_type, Proplists:delete (max_co Nnections, Proplists:delete (shutdown, proplists:delete (socket, transopts))), 
     Case Transport:listen(TRANSOPTS2) of{OK, Socket}-Socket; {error, Reason}-Listen_error (Ref, Transport, TransOpts2, Reason)End; Socket-SocketEnd, {OK, Addr}=Transport:sockname (Lsocket), ranch_server:set_addr (Ref, addr), procs = [{{acceptor, self (), N}, {ranch_acceptor, Start_link, [Lsocket, Transport, Connssup]}, p Ermanent, Brutal_kill, worker, []} | | N <-lists:seq (1 , Nbacceptors)], {OK, {one_for_one,1, 5}, Procs}}.-spec Listen_error (Any (),Module(), any (), Atom ()),No_return (). Listen_error (Ref, Transport, TransOpts2, Reason)-error_logger:error_msg ("Failed to start Ranch listener ~p in ~p:listen (~p) for Reason ~p (~s) ~n", [Ref, Transport, TransOpts2, Reason, Inet:format_error (Reason)]), exit ({listen_error, ref, Reason}).

The most important operations here are

Open port Transport:listen start listening port

Start nbacceptors ranch_accetor:start_link process waits for a connection,

The next step is to view Ranch_acceptor.erl

-Module(ranch_acceptor).-Export([START_LINK/3]).-Export([LOOP/3]).-spec Start_link (Inet:socket (),Module(), PID ())-{OK, pid ()}.start_link (Lsocket, Transport, Connssup)-Pid= Spawn_link (?MODULE, Loop, [Lsocket, Transport, Connssup]), {OK, Pid}.-spec Loop (Inet:socket (),Module(), PID ())No_return (). Loop (Lsocket, Transport, Connssup)-    _ = CaseTransport:accept (Lsocket, Infinity) of{OK, CSocket}- CaseTransport:controlling_process (CSocket, Connssup) ofOK-%%This call won't return until process has been started                    %%And we are below the maximum number of connections.Ranch_conns_sup:start_protocol (Connssup, CSocket); {error, _}-transport:close (CSocket)End; %%Reduce The Accept rate if we run out of file descriptors.        %%we can ' t accept anymore anyway, so We might as well wait        %%a little for the situation to resolve itself.{Error, Emfile}Receive  AfterOkEnd; %%We want to crash if the listening socket got closed.{Error, Reason} whenReason =/= ClosedOKEnd, Flush (),?Module:loop (Lsocket, Transport, Connssup). Flush ()-ReceiveMSG-error_logger:error_msg ("Ranch acceptor received unexpected message: ~p~n", [MSG]), flush () After0-OKEnd.

When the client side is connected, accept returns Ok,ranch_conns_sup:start_protocol send {? MODULE, Start_protocol, self (), Socket} to Connssup,

Start Protocol:start_link detailed, refer to the above Ranch_conns_sup analysis

Well, this time the general structure of the Basic ranch is analyzed, there are some other details to be added slowly later.

Ranch Source Code Analysis (iii)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.