diff options
Diffstat (limited to 'src/cowboy_listener.erl')
-rw-r--r-- | src/cowboy_listener.erl | 19 |
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}; |