From 43d14b52cd07dfd1121bbe6727a96dfd32304e47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Wed, 10 Aug 2011 20:28:30 +0200 Subject: 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. --- src/cowboy_listener.erl | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'src/cowboy_listener.erl') 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}; -- cgit v1.2.3