Condor is a minimal library for building scalable TCP servers in Erlang.
-module(ping_server).
-behaviour(condor_listener).
%% condor_listener callbacks
-export([init/1]).
-export([handle_packet/2]).
-export([handle_info/2]).
-export([terminate/2]).
init([]) ->
{ok, undefined}.
handle_packet(<<"stop">>, State) ->
{send_and_stop, <<"ok">>, normal, State};
handle_packet(<<"ping">>, State) ->
{send, <<"pong">>, State}.
handle_info(_Msg, State) ->
{ok, State}.
terminate(_Reason, _State) ->
ok.
- Reusable supervised connection acceptors
- Neat packet frames and buffers
condor:start_listener(Name, Opts, Module, InitialState) -> {ok, Pid} | {error, Reason} Name = atom() Opts = #{ ip => inet:ip_address(), port => inet:port_number(), max_acceptors => non_neg_integer(), len => 1 | 2, timeout => non_neg_integer() } Module = atom() InitialState = any() Pid = pid() Reason = any()
Opts
:
ip
: to what IP Condor should bind.port
: on what port Condor should listen.max_acceptors
: maximum number of socket acceptors, or in other words, maximum number of concurrent connections.len
: length of the indicator of a packet’s size.timeout
: the time limit, in milliseconds, for a packet to be buffered.
Default Opts
:
#{ ip => {127, 0, 0, 1}, len => 2, timeout => 10000, max_acceptors => 100 }
condor:stop_listener(Name) -> ok Name = atom()
Behaviour: condor_listener
init(State) -> Result handle_packet(Packet, State) -> Result handle_info(Msg, State) -> Result terminate(Reason, State) -> ok Result = {ok, State} | {send, Packet, State} | {stop, Reason, State} | {send_and_stop, Packet, Reason, State} Packet = binary() State = any() Reason = atom()
Events that invoke callbacks:
event callback module ----- --------------- new connection ---> Module:init/1 new packet ---> Module:handle_packet/2 receiving a message ---> Module:handle_info/2 packet timeout ---> Module:handle_info/2 connection termination ---> Module:terminate/2
Condor takes care of framing packets. Each packet frame consists of two
segments: Len | Packet
.
Len
indicates the length of Packet
in big-endian order.
The length of Len
is two bytes by default, though it can be modified with
the len
option.
Condor also takes care of buffering. So, Module:handle_packet/2
is called
only when an entire packet is received. That is, when Packet
is buffered
according to the value of Len
. Len
will then be stripped off, and only
Packet
will be passed to Module:handle_packet/2
. However, if Packet
is
not received completely in Timeout
milliseconds (which would be specified
in Opts
), Module:handle_info/2
will be invoked with Msg
being
{timeout, Buffer :: binary()}
.
A callback’s Result
:
{send, Packet, State}
sendsPacket
(in the frame:Len | Packet
).{stop, Reason, State}
terminates the connection.{send_and_stop, Packet, Reason, State}
sendsPacket
(in the frame:Len | Packet
), and then terminates the connection.
Apache License, Version 2.0