aboutsummaryrefslogtreecommitdiffstats
path: root/src/ranch_server.erl
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2013-04-01 17:04:21 +0200
committerLoïc Hoguin <[email protected]>2013-04-01 17:04:21 +0200
commit109c63d0e76ca6248863932c7a9957f8093cfaf2 (patch)
tree12682f0ec90e57a31ef2e35d67e5440aa0335edb /src/ranch_server.erl
parent33db3b0d1aafcfbc9aadbad622a4014c021ef10c (diff)
downloadranch-109c63d0e76ca6248863932c7a9957f8093cfaf2.tar.gz
ranch-109c63d0e76ca6248863932c7a9957f8093cfaf2.tar.bz2
ranch-109c63d0e76ca6248863932c7a9957f8093cfaf2.zip
Remove ranch_listener and replace ListenerPid by Ref
We just don't need this process anymore. Less, simpler code! API changes: * Protocols start_link first argument is now Ref instead of ListenerPid * ranch:accept_ack/1 argument is now Ref instead of ListenerPid * ranch_listener:remove_connection/1 becomes ranch:remove_connection/1 and its argument is now Ref instead of ListenerPid Ref is the name of the listener given as first argument to start_listener/6.
Diffstat (limited to 'src/ranch_server.erl')
-rw-r--r--src/ranch_server.erl111
1 files changed, 80 insertions, 31 deletions
diff --git a/src/ranch_server.erl b/src/ranch_server.erl
index 77f11c5..d827ae2 100644
--- a/src/ranch_server.erl
+++ b/src/ranch_server.erl
@@ -18,11 +18,16 @@
%% API.
-export([start_link/0]).
--export([insert_listener/2]).
--export([lookup_listener/1]).
+-export([set_new_listener_opts/3]).
+-export([cleanup_listener_opts/1]).
-export([set_connections_sup/2]).
--export([lookup_connections_sup/1]).
--export([find_connections_sup/1]).
+-export([get_connections_sup/1]).
+-export([set_port/2]).
+-export([get_port/1]).
+-export([set_max_connections/2]).
+-export([get_max_connections/1]).
+-export([set_protocol_options/2]).
+-export([get_protocol_options/1]).
-export([count_connections/1]).
%% gen_server.
@@ -47,38 +52,63 @@
start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
-%% @doc Insert a listener into the database.
--spec insert_listener(any(), pid()) -> ok.
-insert_listener(Ref, Pid) ->
- true = ets:insert_new(?TAB, {{listener, Ref}, Pid, undefined}),
- gen_server:cast(?MODULE, {insert_listener, Ref, Pid}).
-
-%% @doc Lookup a listener in the database.
--spec lookup_listener(any()) -> pid().
-lookup_listener(Ref) ->
- ets:lookup_element(?TAB, {listener, Ref}, 2).
+%% @private
+-spec set_new_listener_opts(any(), ranch:max_conns(), any()) -> ok.
+set_new_listener_opts(Ref, MaxConns, Opts) ->
+ gen_server:call(?MODULE, {set_new_listener_opts, Ref, MaxConns, Opts}).
+
+%% @doc Cleanup listener options after it has been stopped.
+-spec cleanup_listener_opts(any()) -> ok.
+cleanup_listener_opts(Ref) ->
+ _ = ets:delete(?TAB, {port, Ref}),
+ _ = ets:delete(?TAB, {max_conns, Ref}),
+ _ = ets:delete(?TAB, {opts, Ref}),
+ ok.
%% @doc Set a connection supervisor associated with specific listener.
-spec set_connections_sup(any(), pid()) -> ok.
set_connections_sup(Ref, Pid) ->
- true = ets:update_element(?TAB, {listener, Ref}, {3, Pid}),
- true = ets:insert_new(?TAB, {{conns_sup, lookup_listener(Ref)}, Pid}),
- ok.
+ gen_server:call(?MODULE, {set_connections_sup, Ref, Pid}).
-%% @doc Lookup a connection supervisor used by specific listener.
--spec lookup_connections_sup(any()) -> pid() | undefined.
-lookup_connections_sup(Ref) ->
- ets:lookup_element(?TAB, {listener, Ref}, 3).
+%% @doc Return the connection supervisor used by specific listener.
+-spec get_connections_sup(any()) -> pid().
+get_connections_sup(Ref) ->
+ ets:lookup_element(?TAB, {conns_sup, Ref}, 2).
-%% @doc Find a connection supervisor using the listener pid.
--spec find_connections_sup(pid()) -> pid().
-find_connections_sup(Pid) ->
- ets:lookup_element(?TAB, {conns_sup, Pid}, 2).
+%% @private
+-spec set_port(any(), inet:port_number()) -> ok.
+set_port(Ref, Port) ->
+ gen_server:call(?MODULE, {set_port, Ref, Port}).
+
+%% @doc Return the listener's port.
+-spec get_port(any()) -> inet:port_number().
+get_port(Ref) ->
+ ets:lookup_element(?TAB, {port, Ref}, 2).
+
+%% @doc Set the max number of connections allowed concurrently.
+-spec set_max_connections(any(), ranch:max_conns()) -> ok.
+set_max_connections(Ref, MaxConnections) ->
+ gen_server:call(?MODULE, {set_max_conns, Ref, MaxConnections}).
+
+%% @doc Return the max number of connections allowed concurrently.
+-spec get_max_connections(any()) -> ranch:max_conns().
+get_max_connections(Ref) ->
+ ets:lookup_element(?TAB, {max_conns, Ref}, 2).
+
+%% @doc Upgrade the protocol options.
+-spec set_protocol_options(any(), any()) -> ok.
+set_protocol_options(Ref, ProtoOpts) ->
+ gen_server:call(?MODULE, {set_opts, Ref, ProtoOpts}).
+
+%% @doc Return the current protocol options.
+-spec get_protocol_options(any()) -> any().
+get_protocol_options(Ref) ->
+ ets:lookup_element(?TAB, {opts, Ref}, 2).
%% @doc Count the number of connections in the connection pool.
-spec count_connections(any()) -> non_neg_integer().
count_connections(Ref) ->
- ranch_conns_sup:active_connections(lookup_connections_sup(Ref)).
+ ranch_conns_sup:active_connections(get_connections_sup(Ref)).
%% gen_server.
@@ -87,14 +117,33 @@ init([]) ->
{ok, #state{}}.
%% @private
+handle_call({set_new_listener_opts, Ref, MaxConns, Opts}, _, State) ->
+ ets:insert(?TAB, {{max_conns, Ref}, MaxConns}),
+ ets:insert(?TAB, {{opts, Ref}, Opts}),
+ {reply, ok, State};
+handle_call({set_connections_sup, Ref, Pid}, _,
+ State=#state{monitors=Monitors}) ->
+ true = ets:insert_new(?TAB, {{conns_sup, Ref}, Pid}),
+ MonitorRef = erlang:monitor(process, Pid),
+ {reply, ok, State#state{
+ monitors=[{{MonitorRef, Pid}, Ref}|Monitors]}};
+handle_call({set_port, Ref, Port}, _, State) ->
+ true = ets:insert(?TAB, {{port, Ref}, Port}),
+ {reply, ok, State};
+handle_call({set_max_conns, Ref, MaxConns}, _, State) ->
+ ets:insert(?TAB, {{max_conns, Ref}, MaxConns}),
+ ConnsSup = get_connections_sup(Ref),
+ ConnsSup ! {set_max_conns, MaxConns},
+ {reply, ok, State};
+handle_call({set_opts, Ref, Opts}, _, State) ->
+ ets:insert(?TAB, {{opts, Ref}, Opts}),
+ ConnsSup = get_connections_sup(Ref),
+ ConnsSup ! {set_opts, Opts},
+ {reply, ok, State};
handle_call(_Request, _From, State) ->
{reply, ignore, State}.
%% @private
-handle_cast({insert_listener, Ref, Pid}, State=#state{monitors=Monitors}) ->
- MonitorRef = erlang:monitor(process, Pid),
- {noreply, State#state{
- monitors=[{{MonitorRef, Pid}, Ref}|Monitors]}};
handle_cast(_Request, State) ->
{noreply, State}.
@@ -102,7 +151,7 @@ handle_cast(_Request, State) ->
handle_info({'DOWN', MonitorRef, process, Pid, _},
State=#state{monitors=Monitors}) ->
{_, Ref} = lists:keyfind({MonitorRef, Pid}, 1, Monitors),
- true = ets:delete(?TAB, {listener, Ref}),
+ true = ets:delete(?TAB, {conns_sup, Ref}),
Monitors2 = lists:keydelete({MonitorRef, Pid}, 1, Monitors),
{noreply, State#state{monitors=Monitors2}};
handle_info(_Info, State) ->