Oscar Hellström committed 1c7f1c4

Enable configuration of connection timeouts.

Comments (0)

Files changed (4)

-* Erlang/OTP R12-B or newer (compiler to build, kernel and stdlib to run)
-* GNU Make (might actually build with some other make as well)
+ * Erlang/OTP R12-B or newer (compiler to build, kernel and stdlib to run)
+ * GNU Make (might actually build with some other make as well)
+ * Eunit (for testing)
 To bulid the application simply run 'make'. This should build .beam, .app
 files and documentation.
+Configuration: (environment variables)
+ * connection_timeout: The time (in milliseconds) the client will try to
+                       kepp a HTTP/1.1 connection open. Changing this value
+                       in runtime has no effect, this can however be done
+                       through lhttpc_manager:update_connection_timeout/1.
+There are some interesting make targets:
+ * test - Will compile and run all tests (using eunit)
+ * dialyzer - Will run dialyzer on the application


 @doc A lightweight HTTP client.
 The only functions of much interest right now are {@link
 lhttpc:request/4} and {@link lhttpc:request/5}.
+The maximume time (in milliseconds) the client will keep a TCP connection
+open to a server.


         {registered, [lhttpc_manager]},
         {applications, [kernel, stdlib]},
   {mod, {lhttpc, nil}},
-  {env, []}
+  {env, [{connection_timeout, 300000}]}


 %%% @end
--export([start_link/0, connection_count/0, connection_count/1]).
+        start_link/0,
+        connection_count/0,
+        connection_count/1,
+        update_connection_timeout/1
+    ]).
--record(httpc_man, {destinations = dict:new(), sockets = dict:new()}).
+-record(httpc_man, {
+        destinations = dict:new(),
+        sockets = dict:new(),
+        timeout = 300000 :: non_neg_integer()
+    }).
 %% @spec () -> Count
 %%    Count = integer()
     Destination = {string:to_lower(Host), Port, Ssl},
     gen_server:call(?MODULE, {connection_count, Destination}).
+%% @spec (Timeout) -> ok
+%%    Timeout = intetger()
+%% @doc Updates the timeout for persistent connections.
+%% This will only affect future sockets handed to the manager. The sockets
+%% already managed will keep their timers.
+%% @end
+-spec update_connection_timeout(non_neg_integer()) -> ok.
+update_connection_timeout(Milliseconds) ->
+    gen_server:cast(?MODULE, {update_timeout, Milliseconds}).
 %% @spec () -> {ok, pid()}
 %% @doc Starts and link to the gen server.
 %% This is normally called by a supervisor.
 -spec init(any()) -> {ok, #httpc_man{}}.
 init(_) ->
     process_flag(priority, high),
-    {ok, #httpc_man{}}.
+    State = case application:get_env(lhttpc, connection_timeout) of
+        undefined     -> #httpc_man{};
+        {ok, Timeout} -> #httpc_man{timeout = Timeout}
+    end,
+    {ok, State}.
 %% @hidden
 -spec handle_call(any(), any(), #httpc_man{}) ->
 handle_cast({done, Host, Port, Ssl, Socket}, State) ->
     NewState = store_socket({Host, Port, Ssl}, Socket, State),
     {noreply, NewState};
+handle_cast({update_timeout, Milliseconds}, State) ->
+    {noreply, State#httpc_man{timeout = Milliseconds}};
 handle_cast(_, State) ->
     {noreply, State}.
 store_socket({_, _, Ssl} = Destination, Socket, State) ->
-    % we want to time out on the socket, should the time be an option?
-    Timer = erlang:send_after(300000, self(), {timeout, Socket}), 
+    Timeout = State#httpc_man.timeout,
+    Timer = erlang:send_after(Timeout, self(), {timeout, Socket}),
     % the socket might be closed from the other side
     lhttpc_sock:setopts(Socket, [{active, once}], Ssl),
     Destinations = State#httpc_man.destinations,
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.