diff options
author | Loïc Hoguin <[email protected]> | 2011-08-10 20:28:30 +0200 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2011-08-10 20:28:30 +0200 |
commit | 43d14b52cd07dfd1121bbe6727a96dfd32304e47 (patch) | |
tree | 5b8d451d0decec8e75cf70c24e5c3fb54f51a65c /src/cowboy_listener.erl | |
parent | 56369d5c1a0a3141e9d136b2f8010ff0e96bb26c (diff) | |
download | cowboy-43d14b52cd07dfd1121bbe6727a96dfd32304e47.tar.gz cowboy-43d14b52cd07dfd1121bbe6727a96dfd32304e47.tar.bz2 cowboy-43d14b52cd07dfd1121bbe6727a96dfd32304e47.zip |
Give the ListenerPid to the protocol on startup
Also sends a message 'shoot' that can be received by the protocol
to make sure Cowboy has had enough time to fully initialize the
socket. This message should be received before any socket-related
operations are performed.
WebSocket request connections are now moved from the pool 'default'
to the pool 'websocket', meaning we can have a lot of running
WebSockets despite having a low 'max_connections' setting.
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}; |