From: Jakub Narebski <jnareb@gmail.com>
To: "J.H." <warthog9@kernel.org>
Cc: git@vger.kernel.org, "John 'Warthog9' Hawley" <warthog9@eaglescrag.net>
Subject: [PATCHv2 1/6] gitweb: Load checking
Date: Fri, 18 Dec 2009 17:36:04 +0100 [thread overview]
Message-ID: <200912181736.07008.jnareb@gmail.com> (raw)
In-Reply-To: <200912111109.17047.jnareb@gmail.com>
From: John 'Warthog9' Hawley <warthog9@kernel.org>
This changes slightly the behavior of gitweb, so that it verifies
that the box isn't inundated with before attempting to serve gitweb.
If the box is overloaded, it basically returns a 503 Server Unavailable
until the load falls below the defined threshold. This helps dramatically
if you have a box that's I/O bound, reaches a certain load and you
don't want gitweb, the I/O hog that it is, increasing the pain the
server is already undergoing.
This behavior is controlled by $maxload configuration variable.
Default is a load of 300, which for most cases should never be hit.
Unset it (set it to undefined value, i.e. undef) to turn off checking.
Currently it requires that '/proc/loadavg' file exists, otherwise the
load check is bypassed (load is taken to be 0). So platforms that do
not implement '/proc/loadavg' currently cannot use this feature.
Signed-off-by: John 'Warthog9' Hawley <warthog9@kernel.org>
Signed-off-by: Jakub Narebski <jnareb@gmail.com>
---
This is my take on this patch, with all my concerns taken into
consideration... well, all except describing alterante approaches
to straight using /proc/loadavg.
Differences to original version by John 'Warthog9' Hawley (J.H.):
* Slightly improved wording in commit message and in comments
* $maxload described in gitweb/README, in "Gitweb config file variables"
section
* You can use '$maxload = undef;' to turn off load checking
* Error page for too high load is generated using die_error, which had
to be extended to handle 503 Service Unavailable HTTP error code
gitweb/README | 7 ++++++-
gitweb/gitweb.perl | 39 +++++++++++++++++++++++++++++++++++----
2 files changed, 41 insertions(+), 5 deletions(-)
diff --git a/gitweb/README b/gitweb/README
index e34ee79..6c2c8e1 100644
--- a/gitweb/README
+++ b/gitweb/README
@@ -174,7 +174,7 @@ not include variables usually directly set during build):
Base URL for relative URLs in pages generated by gitweb,
(e.g. $logo, $favicon, @stylesheets if they are relative URLs),
needed and used only for URLs with nonempty PATH_INFO via
- <base href="$base_url>. Usually gitweb sets its value correctly,
+ <base href="$base_url">. Usually gitweb sets its value correctly,
and there is no need to set this variable, e.g. to $my_uri or "/".
* $home_link
Target of the home link on top of all pages (the first part of view
@@ -228,6 +228,11 @@ not include variables usually directly set during build):
repositories from launching cross-site scripting (XSS) attacks. Set this
to true if you don't trust the content of your repositories. The default
is false.
+ * $maxload
+ Used to set the maximum load that we will still respond to gitweb queries.
+ If server load exceed this value then return "503 Service Unavaliable" error.
+ Server load is taken to be 0 if gitweb cannot determine its value. Set it to
+ undefined value to turn it off. The default is 300.
Projects list file format
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index 7e477af..a0f0444 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -221,6 +221,12 @@ our %avatar_size = (
'double' => 32
);
+# Used to set the maximum load that we will still respond to gitweb queries.
+# If server load exceed this value then return "503 server busy" error.
+# If gitweb cannot determined server load, it is taken to be 0.
+# Leave it undefined (or set to 'undef') to turn off load checking.
+our $maxload = 300;
+
# You define site-wide feature defaults here; override them with
# $GITWEB_CONFIG as necessary.
our %feature = (
@@ -551,6 +557,26 @@ if (-e $GITWEB_CONFIG) {
do $GITWEB_CONFIG_SYSTEM if -e $GITWEB_CONFIG_SYSTEM;
}
+# Get loadavg of system, to compare against $maxload.
+# Currently it requires '/proc/loadavg' present to get loadavg;
+# if it is not present it returns 0, which means no load checking.
+sub get_loadavg {
+ open my $fd, '<', '/proc/loadavg'
+ or return 0;
+ my @load = split(/\s+/, scalar <$fd>);
+ close $fd;
+
+ # The first three columns measure CPU and IO utilization of the last one,
+ # five, and 10 minute periods. The fourth column shows the number of
+ # currently running processes and the total number of processes in the m/n
+ # format. The last column displays the last process ID used.
+ return $load[0] || 0;
+}
+
+if (defined $maxload && get_loadavg() > $maxload) {
+ die_error(503, "The load average on the server is too high");
+}
+
# version of the core git binary
our $git_version = qx("$GIT" --version) =~ m/git version (.*)$/ ? $1 : "unknown";
$number_of_git_cmds++;
@@ -3354,14 +3380,19 @@ sub git_footer_html {
# 500: The server isn't configured properly, or
# an internal error occurred (e.g. failed assertions caused by bugs), or
# an unknown error occurred (e.g. the git binary died unexpectedly).
+# 503: The server is currently unavailable (because it is overloaded,
+# or down for maintenance). Generally, this is a temporary state.
sub die_error {
my $status = shift || 500;
my $error = shift || "Internal server error";
- my %http_responses = (400 => '400 Bad Request',
- 403 => '403 Forbidden',
- 404 => '404 Not Found',
- 500 => '500 Internal Server Error');
+ my %http_responses = (
+ 400 => '400 Bad Request',
+ 403 => '403 Forbidden',
+ 404 => '404 Not Found',
+ 500 => '500 Internal Server Error',
+ 503 => '503 Service Unavailable',
+ );
git_header_html($http_responses{$status});
print <<EOF;
<div class="page_body">
--
1.6.5.3
next prev parent reply other threads:[~2009-12-18 16:36 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-12-10 23:45 [PATCH 0/6] Gitweb caching changes v2 John 'Warthog9' Hawley
2009-12-10 23:45 ` [PATCH 1/6] GITWEB - Load Checking John 'Warthog9' Hawley
2009-12-10 23:45 ` [PATCH 2/6] GITWEB - Missmatching git w/ gitweb John 'Warthog9' Hawley
2009-12-10 23:45 ` [PATCH 3/6] GITWEB - Add git:// link to summary pages John 'Warthog9' Hawley
2009-12-10 23:45 ` [PATCH 4/6] GITWEB - Makefile changes John 'Warthog9' Hawley
[not found] ` <1260488743-25855-6-git-send-email-warthog9@kernel.org>
2009-12-10 23:45 ` [PATCH 6/6] GITWEB - Separate defaults from main file John 'Warthog9' Hawley
2009-12-11 15:46 ` Jakub Narebski
2009-12-11 15:58 ` J.H.
2009-12-11 22:53 ` Jakub Narebski
2009-12-16 1:22 ` Junio C Hamano
2009-12-16 2:00 ` J.H.
2009-12-16 19:52 ` Jakub Narebski
2009-12-16 20:04 ` J.H.
2009-12-16 2:22 ` Jakub Narebski
2009-12-11 14:28 ` [PATCH 4/6] GITWEB - Makefile changes Jakub Narebski
2009-12-11 16:22 ` J.H.
2009-12-11 16:41 ` Jakub Narebski
2009-12-19 13:32 ` [PATCH/RFCv2 4/6] gitweb: Makefile improvements Jakub Narebski
2009-12-11 12:52 ` [PATCH 3/6] GITWEB - Add git:// link to summary pages Johannes Schindelin
2009-12-11 13:44 ` Jakub Narebski
2009-12-18 21:02 ` [PATCHv2 3/6] gitweb: Optionally add "git" links in project list page Jakub Narebski
2009-12-11 10:52 ` [PATCH 2/6] GITWEB - Missmatching git w/ gitweb Jakub Narebski
2009-12-18 19:18 ` [RFC/PATCHv2 2/6] gitweb: Add option to force version match Jakub Narebski
2009-12-11 12:49 ` [PATCH 2/6] GITWEB - Missmatching git w/ gitweb Johannes Schindelin
2009-12-10 23:54 ` [PATCH 1/6] GITWEB - Load Checking Sverre Rabbelier
2009-12-11 0:52 ` Jakub Narebski
2009-12-11 1:10 ` Junio C Hamano
2009-12-11 2:19 ` J.H.
2009-12-11 2:50 ` Junio C Hamano
2009-12-11 2:58 ` J.H.
2009-12-11 3:07 ` J.H.
2009-12-11 3:09 ` Junio C Hamano
2009-12-11 10:09 ` Jakub Narebski
2009-12-18 16:36 ` Jakub Narebski [this message]
2009-12-11 13:53 ` Mihamina Rakotomandimby
2009-12-10 23:53 ` [PATCH 0/6] Gitweb caching changes v2 Sverre Rabbelier
2009-12-11 15:51 ` Jakub Narebski
[not found] ` <4B226D56.7000004@kernel.org>
2009-12-11 18:01 ` Jakub Narebski
2009-12-11 18:26 ` J.H.
2009-12-12 1:37 ` Jakub Narebski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200912181736.07008.jnareb@gmail.com \
--to=jnareb@gmail.com \
--cc=git@vger.kernel.org \
--cc=warthog9@eaglescrag.net \
--cc=warthog9@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).