Permalink
Browse files

Adding an option to bypass pools entirely

In some cases, a few high priority requests happening with
a low frequency may be seen as admissible -- for example,
important error messages, diagnostic polls, and so on.

This change adds the possibility set the option 'max_connections'
to {max_connections, bypass} to have a socket opened that does
not respect a given's Scheme+Host+Port's pool limits and opens
a socket outside of it.

This socket will be closed as soon as the response is obtained.
  • Loading branch information...
1 parent 73769cb commit b3fab258daaa7b85fec7544656743c9876146e38 @ferd committed Oct 24, 2012
Showing with 24 additions and 11 deletions.
  1. +3 −1 include/lhttpc_types.hrl
  2. +7 −3 src/lhttpc.erl
  3. +14 −7 src/lhttpc_client.erl
View
@@ -33,7 +33,9 @@
{connect_timeout, timeout()} |
{send_retry, non_neg_integer()} |
{partial_upload, non_neg_integer() | infinity} |
- {partial_download, pid(), non_neg_integer() | infinity}.
+ {partial_download, pid(), non_neg_integer() | infinity} |
+ {stream_to, pid()} |
+ {max_connections, pos_integer() | bypass}.
-type options() :: [option()].
View
@@ -158,7 +158,9 @@ request(URL, Method, Hdrs, Body, Timeout) ->
%% {connect_options, [ConnectOptions]} |
%% {send_retry, integer()} |
%% {partial_upload, WindowSize} |
-%% {partial_download, PartialDownloadOptions}
+%% {partial_download, PartialDownloadOptions} |
+%% {stream_to, pid()} |
+%% {max_connections, pos_integer() | bypass}
%% Milliseconds = integer()
%% ConnectOptions = term()
%% WindowSize = integer() | infinity
@@ -205,7 +207,9 @@ request(URL, Method, Hdrs, Body, Timeout, Options) ->
%% {connect_options, [ConnectOptions]} |
%% {send_retry, integer()} |
%% {partial_upload, WindowSize} |
-%% {partial_download, PartialDownloadOptions}
+%% {partial_download, PartialDownloadOptions} |
+%% {stream_to, pid()} |
+%% {max_connections, pos_integer() | bypass}
%% Milliseconds = integer()
%% WindowSize = integer()
%% PartialDownloadOptions = [PartialDownloadOption]
@@ -575,7 +579,7 @@ verify_options([{connection_timeout, MS} | Options], Errors)
when is_integer(MS), MS >= 0 ->
verify_options(Options, Errors);
verify_options([{max_connections, N} | Options], Errors)
- when is_integer(N), N > 0 ->
+ when is_integer(N), N > 0; N =:= bypass ->
verify_options(Options, Errors);
verify_options([{partial_upload, WindowSize} | Options], Errors)
when is_integer(WindowSize), WindowSize >= 0 ->
View
@@ -106,10 +106,14 @@ execute(ReqId, From, Host, Port, Ssl, Path, Method, Hdrs, Body, Options) ->
ConnectionTimeout = proplists:get_value(connection_timeout, Options, infinity),
{ChunkedUpload, Request} = lhttpc_lib:format_request(Path, NormalizedMethod,
Hdrs, Host, Port, Body, PartialUpload),
- Socket = case lhttpc_lb:checkout(Host, Port, Ssl, MaxConnections, ConnectionTimeout) of
- {ok, S} -> S; % Re-using HTTP/1.1 connections
- retry_later -> throw(retry_later);
- no_socket -> undefined % Opening a new HTTP/1.1 connection
+ Socket = case MaxConnections of
+ bypass -> undefined;
+ _Number ->
+ case lhttpc_lb:checkout(Host, Port, Ssl, MaxConnections, ConnectionTimeout) of
+ {ok, S} -> S; % Re-using HTTP/1.1 connections
+ retry_later -> throw(retry_later);
+ no_socket -> undefined % Opening a new HTTP/1.1 connection
+ end
end,
State = #client_state{
req_id = ReqId,
@@ -134,10 +138,13 @@ execute(ReqId, From, Host, Port, Ssl, Path, Method, Hdrs, Body, Options) ->
part_size = proplists:get_value(part_size,
PartialDownloadOptions, infinity)
},
- Response = case send_request(State) of
- {R, undefined} ->
+ Response = case {MaxConnections, send_request(State)} of
+ {_, {R, undefined}} ->
+ {ok, R};
+ {bypass, {R, NewSocket}} ->
+ lhttpc_sock:close(NewSocket, Ssl),
{ok, R};
- {R, NewSocket} ->
+ {_, {R, NewSocket}} ->
% The socket we ended up doing the request over is returned
% here, it might be the same as Socket, but we don't know.
lhttpc_lb:checkin(Host, Port, Ssl, NewSocket),

0 comments on commit b3fab25

Please sign in to comment.