Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added a new configuration parameter called "keepalive_maxuses" which …

…allows

the yaws admin to close persistant connections after X number of uses. This
is handy for some types of system which may generate a lot of garbage in the
process in the erlang VM or for other reasons where you want to limit how
many requests can be processed on a single connection. The default setting
remains unlimited.
  • Loading branch information...
commit 0446f2b8777ca47309deebe95198812572f4ff03 1 parent 59432b5
Thomas O'Dowd authored
View
3  include/yaws.hrl
@@ -74,6 +74,7 @@
ebin_dir = [],
runmods = [], %% runmods for entire server
keepalive_timeout = 15000,
+ keepalive_maxuses = nolimit, %% nolimit or non negative integer
max_num_cached_files = 400,
max_num_cached_bytes = 1000000, %% 1 MEG
max_size_cached_file = 8000,
@@ -270,6 +271,8 @@
doclose, %% bool
chunked, %% bool
+ exceedmaxuses=false,
+ %% bool, true if hit keep-alive max uses
encoding=identity,
%% identity, deflate
contlen, %% integer
View
8 man/yaws.conf.5
@@ -108,6 +108,14 @@ from HTTP clients into the server. This is implemented by closing
the last socket if the limit threshold is reached.
.TP
+\fB keepalive_maxuses = nolimit | <int>\fR
+Normally, yaws does not restrict the number of times a connection is
+kept alive using keepalive. Setting this parameter to an integer X
+will ensure that connections are closed once they have been used X times.
+This can be a useful to guard against long running connections
+collecting too much garbage in the erlang VM.
+
+.TP
\fB process_options = "[]" | "[{fullsweep_after, int()} | {min_heap_size, int()}]"\fR
Override the garbage collection option parameters for processes
which handle new connections. Useful for systems which expect long lived
View
7 scripts/yaws.conf.template
@@ -29,6 +29,13 @@ include_dir = %yawsdir%/examples/include
# max number of connections from clients into the server
max_connections = nolimit
+# Normally, yaws does not restrict the number of times a connection is
+# kept alive using keepalive. Setting this parameter to an integer X
+# will ensure that connections are closed once they have been used X times.
+# This can be a useful to guard against long running connections
+# collecting too much garbage in the erlang VM.
+keepalive_maxuses = nolimit
+
# Override the garbage collection option parameters for processes
# which handle new connections. Useful for systems which expect long lived
# connections which handle a lot of data. The default value is erlangs
View
5 src/yaws.erl
@@ -55,7 +55,7 @@
outh_set_content_length/1,
outh_set_dcc/2,
outh_set_transfer_encoding_off/0,
- outh_set_auth/1,
+ outh_set_auth/1,
outh_fix_doclose/0,
dcc/2]).
@@ -1303,7 +1303,10 @@ outh_fix_doclose() ->
dcc(Req, Headers) ->
+ H = get(outh),
DoClose = case Req#http_request.version of
+ _ when H#outh.exceedmaxuses == true ->
+ true; %% too many keepalives
{1, 0} ->
case Headers#headers.connection of
"close" -> true;
View
12 src/yaws_config.erl
@@ -659,6 +659,18 @@ fload(FD, globals, GC, C, Cs, Lno, Chars) ->
{error, ?F("Expect integer at line ~w", [Lno])}
end;
+ ["keepalive_maxuses", '=', Int] ->
+ case (catch list_to_integer(Int)) of
+ I when is_integer(I) ->
+ fload(FD, globals, GC#gconf{keepalive_maxuses = I},
+ C, Cs, Lno+1, Next);
+ _ when Int == "nolimit" ->
+ %% nolimit is the default
+ fload(FD, globals, GC, C, Cs, Lno+1, Next);
+ _ ->
+ {error, ?F("Expect integer at line ~w", [Lno])}
+ end;
+
["php_exe_path", '=' , PhpPath] ->
case is_file(PhpPath) of
true ->
View
38 src/yaws_server.erl
@@ -1082,9 +1082,11 @@ aloop(CliSock, GS, Num) ->
end,
put(outh, #outh{}),
put(sc, SC),
- yaws_stats:hit(),
+ yaws_stats:hit(),
+ check_keepalive_maxuses(GS, Num),
Call = call_method(Req#http_request.method, CliSock, Req, H),
- handle_method_result(Call, CliSock, IP, GS, Req, H, Num);
+ Call2 = fix_keepalive_maxuses(Call),
+ handle_method_result(Call2, CliSock, IP, GS, Req, H, Num);
closed ->
{ok, Num};
_ ->
@@ -1092,6 +1094,34 @@ aloop(CliSock, GS, Num) ->
exit(normal)
end.
+%% Checks how many times keepalive has been used and updates the
+%% process dictionary outh variable if required to say that the
+%% connection has exceeded its maxuses.
+check_keepalive_maxuses(GS, Num) ->
+ case (GS#gs.gconf)#gconf.keepalive_maxuses of
+ nolimit ->
+ ok;
+ 0 ->
+ ok;
+ N when Num+1 < N ->
+ ok;
+ _N ->
+ put(outh, (get(outh))#outh{exceedmaxuses=true})
+ end.
+
+%% Change to Res to 'done' if we've exceeded our maxuses.
+fix_keepalive_maxuses(Res) ->
+ case Res of
+ continue ->
+ case (get(outh))#outh.exceedmaxuses of
+ true ->
+ done; %% no keepalive this time!
+ _ ->
+ Res
+ end;
+ _ ->
+ Res
+ end.
%% keep original dictionary but filter out eventual previous init_db
%% in erase_transients/0
@@ -1151,11 +1181,13 @@ handle_method_result(Res, CliSock, IP, GS, Req, H, Num) ->
ok
end,
put (sc, (get(sc))#sconf{appmods = []}),
+ check_keepalive_maxuses(GS, Num),
Call = call_method(Req#http_request.method,
CliSock,
Req#http_request{path = {abs_path, Page}},
H#headers{content_length = undefined}),
- handle_method_result(Call, CliSock, IP, GS, Req, H, Num)
+ Call2 = fix_keepalive_maxuses(Call),
+ handle_method_result(Call2, CliSock, IP, GS, Req, H, Num)
end.
Please sign in to comment.
Something went wrong with that request. Please try again.