Skip to content

Commit

Permalink
Move gen_server calls into lhttpc_manager module.
Browse files Browse the repository at this point in the history
  • Loading branch information
lastres committed Jan 17, 2013
1 parent 1340bc6 commit bea0276
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 53 deletions.
56 changes: 4 additions & 52 deletions src/lhttpc_client.erl
Original file line number Diff line number Diff line change
Expand Up @@ -136,10 +136,11 @@ execute(From, Host, Port, Ssl, Path, Method, Hdrs, Body, Options) ->
end,
{ChunkedUpload, Request} = lhttpc_lib:format_request(Path, NormalizedMethod,
Hdrs, Host, Port, Body, PartialUpload),
SocketRequest = {socket, self(), Host, Port, Ssl},
%SocketRequest = {socket, self(), Host, Port, Ssl},
Pool = proplists:get_value(pool, Options, whereis(lhttpc_manager)),
%% Get a socket for the pool or exit
Socket = ensure_call(Pool, SocketRequest, Options),
%Socket = lhttpc_manager:ensure_call(Pool, SocketRequest, Options),
Socket = lhttpc_manager:ensure_call(Pool, self(), Host, Port, Ssl, Options),
State = #client_state{
host = Host,
port = Port,
Expand Down Expand Up @@ -177,60 +178,11 @@ execute(From, Host, Port, Ssl, Path, Method, Hdrs, Body, Options) ->
% * The socket was closed remotely already
% * Due to an error in this module (returning dead sockets for
% instance)
case lhttpc_sock:controlling_process(NewSocket, Pool, Ssl) of
ok ->
DoneMsg = {done, Host, Port, Ssl, NewSocket},
ok = gen_server:call(Pool, DoneMsg, infinity);
_ ->
ok
end,
ok = lhttpc_manager:client_done(Pool, Host, Port, Ssl, NewSocket),
{ok, R}
end,
{response, self(), Response}.

%%------------------------------------------------------------------------------
%% @doc If call contains pool_ensure option, dynamically create the pool with
%% configured parameters. Checks the pool for a socket connected to the
%% destination and returns it if it exists, 'undefined' otherwise.
%% @end
%%------------------------------------------------------------------------------
ensure_call(Pool, SocketRequest, Options) ->
try gen_server:call(Pool, SocketRequest, infinity) of
{ok, S} ->
%% Re-using HTTP/1.1 connections
S;
no_socket ->
%% Opening a new HTTP/1.1 connection
undefined
catch
exit:{noproc, Reason} ->
case proplists:get_value(pool_ensure, Options, false) of
true ->
{ok, DefaultTimeout} = application:get_env(
lhttpc,
connection_timeout),
ConnTimeout = proplists:get_value(pool_connection_timeout,
Options,
DefaultTimeout),
{ok, DefaultMaxPool} = application:get_env(
lhttpc,
pool_size),
PoolMaxSize = proplists:get_value(pool_max_size,
Options,
DefaultMaxPool),
case lhttpc:add_pool(Pool, ConnTimeout, PoolMaxSize) of
{ok, _Pid} ->
ensure_call(Pool, SocketRequest, Options);
_ ->
%% Failed to create pool, exit as expected
exit({noproc, Reason})
end;
false ->
%% No dynamic pool creation, exit as expected
exit({noproc, Reason})
end
end.

%%------------------------------------------------------------------------------
%% @private
%% @doc This function creates a new socket connection if needed, and it also
Expand Down
65 changes: 64 additions & 1 deletion src/lhttpc_manager.erl
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@
update_connection_timeout/2,
dump_settings/1,
list_pools/0,
set_max_pool_size/2
set_max_pool_size/2,
ensure_call/6,
client_done/5
]).

%% Callbacks
Expand Down Expand Up @@ -186,6 +188,67 @@ start_link(Options0) ->
gen_server:start_link({local, Name}, ?MODULE, Options, [])
end.

%%------------------------------------------------------------------------------
%% @doc If call contains pool_ensure option, dynamically create the pool with
%% configured parameters. Checks the pool for a socket connected to the
%% destination and returns it if it exists, 'undefined' otherwise.
%% @end
%%------------------------------------------------------------------------------
-spec ensure_call(pool_id(), pid(), host(), port_num(), boolean(), options()) ->
socket() | 'no_socket'.
ensure_call(Pool, Pid, Host, Port, Ssl, Options) ->
SocketRequest = {socket, Pid, Host, Port, Ssl},
try gen_server:call(Pool, SocketRequest, infinity) of
{ok, S} ->
%% Re-using HTTP/1.1 connections
S;
no_socket ->
%% Opening a new HTTP/1.1 connection
undefined
catch
exit:{noproc, Reason} ->
case proplists:get_value(pool_ensure, Options, false) of
true ->
{ok, DefaultTimeout} = application:get_env(
lhttpc,
connection_timeout),
ConnTimeout = proplists:get_value(pool_connection_timeout,
Options,
DefaultTimeout),
{ok, DefaultMaxPool} = application:get_env(
lhttpc,
pool_size),
PoolMaxSize = proplists:get_value(pool_max_size,
Options,
DefaultMaxPool),
case lhttpc:add_pool(Pool, ConnTimeout, PoolMaxSize) of
{ok, _Pid} ->
ensure_call(Pool, Pid, Host, Port, Ssl, Options);
_ ->
%% Failed to create pool, exit as expected
exit({noproc, Reason})
end;
false ->
%% No dynamic pool creation, exit as expected
exit({noproc, Reason})
end
end.

%%------------------------------------------------------------------------------
%% @doc A client has finished one request and returns the socket to the pool,
%% which can be new or not.
%% @end
%%------------------------------------------------------------------------------
-spec client_done(pid(), host(), port_num(), boolean(), socket()) -> ok.
client_done(Pool, Host, Port, Ssl, Socket) ->
case lhttpc_sock:controlling_process(Socket, Pool, Ssl) of
ok ->
DoneMsg = {done, Host, Port, Ssl, Socket},
ok = gen_server:call(Pool, DoneMsg, infinity);
_ ->
ok
end.

%%==============================================================================
%% Callbacks
%%==============================================================================
Expand Down

0 comments on commit bea0276

Please sign in to comment.