aboutsummaryrefslogtreecommitdiffstats
path: root/src/cowboy_listener.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/cowboy_listener.erl')
-rw-r--r--src/cowboy_listener.erl19
1 files changed, 18 insertions, 1 deletions
diff --git a/src/cowboy_listener.erl b/src/cowboy_listener.erl
index 2f5ccc2..8b656ba 100644
--- a/src/cowboy_listener.erl
+++ b/src/cowboy_listener.erl
@@ -17,7 +17,7 @@
-behaviour(gen_server).
-export([start_link/0, stop/1,
- add_connection/3, remove_connection/2, wait/3]). %% API.
+ add_connection/3, move_connection/3, remove_connection/2, wait/3]). %% API.
-export([init/1, handle_call/3, handle_cast/2,
handle_info/2, terminate/2, code_change/3]). %% gen_server.
@@ -54,6 +54,11 @@ stop(ServerPid) ->
add_connection(ServerPid, Pool, ConnPid) ->
gen_server:call(ServerPid, {add_connection, Pool, ConnPid}).
+%% @doc Move a connection from one pool to another.
+-spec move_connection(pid(), atom(), pid()) -> ok.
+move_connection(ServerPid, DestPool, ConnPid) ->
+ gen_server:cast(ServerPid, {move_connection, DestPool, ConnPid}).
+
%% @doc Remove the given connection from its pool.
-spec remove_connection(pid(), pid()) -> ok.
remove_connection(ServerPid, ConnPid) ->
@@ -107,6 +112,18 @@ handle_call(_Request, _From, State) ->
%% @private
-spec handle_cast(_, State) -> {noreply, State}.
+handle_cast({move_connection, DestPool, ConnPid}, State=#state{
+ req_pools=Pools, reqs_table=ReqsTable}) ->
+ {MonitorRef, SrcPool} = ets:lookup_element(ReqsTable, ConnPid, 2),
+ ets:insert(ReqsTable, {ConnPid, {MonitorRef, DestPool}}),
+ {SrcPool, SrcNbConns} = lists:keyfind(SrcPool, 1, Pools),
+ DestNbConns = case lists:keyfind(DestPool, 1, Pools) of
+ false -> 1;
+ {DestPool, NbConns} -> NbConns + 1
+ end,
+ Pools2 = lists:keydelete(SrcPool, 1, lists:keydelete(DestPool, 1, Pools)),
+ Pools3 = [{SrcPool, SrcNbConns - 1}, {DestPool, DestNbConns}|Pools2],
+ {noreply, State#state{req_pools=Pools3}};
handle_cast({remove_connection, ConnPid}, State) ->
State2 = remove_pid(ConnPid, State),
{noreply, State2};