Created
September 8, 2010 03:47
-
-
Save mnot/569583 to your computer and use it in GitHub Desktop.
mod_loadshed.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* \file mod_loadshed.c | |
* \author Mark Nottingham, <mnot@mnot.net> | |
* | |
* mod_loadshed, when enabled, will refuse the request with a 503 if | |
* no additional Apache children are currently available. This should | |
* prevent requests from going to the listen queue. | |
*/ | |
#include "httpd.h" | |
#include "http_core.h" | |
#include "http_config.h" | |
#include "http_log.h" | |
#include "scoreboard.h" | |
#include <stdio.h> | |
MODULE_VAR_EXPORT module loadshed_module; | |
typedef struct { | |
int enabled; | |
} loadshed_cfg; | |
static void *mkconfig(pool *p) | |
{ | |
loadshed_cfg *cfg = ap_pcalloc(p, sizeof(loadshed_cfg)); | |
cfg->enabled = 0; | |
return cfg; | |
} | |
/* | |
* Respond to a callback to create configuration record for a server or | |
* vhost environment. | |
*/ | |
static void *create_mconfig_for_server(pool *p, server_rec *s) | |
{ | |
return mkconfig(p); | |
} | |
/* | |
* Respond to a callback to create a config record for a specific directory. | |
*/ | |
static void *create_mconfig_for_directory(pool *p, char *dir) | |
{ | |
return mkconfig(p); | |
} | |
/* | |
* Handler for the LoadShed directive, which is FLAG. | |
*/ | |
static const char *set_loadshed(cmd_parms *cmd, void *mconfig, int arg) | |
{ | |
loadshed_cfg *cfg = (loadshed_cfg *) mconfig; | |
cfg->enabled = arg; | |
return NULL; | |
} | |
static int check_loadshed(request_rec *r) | |
{ | |
loadshed_cfg *cfg; | |
int i, res; | |
short_score score_record; | |
int ready = 0; | |
cfg = ap_get_module_config(r->per_dir_config, &loadshed_module); | |
if (cfg->enabled) { | |
// ap_sync_scoreboard_image(); | |
for (i = 0; i < HARD_SERVER_LIMIT; ++i) { | |
score_record = ap_scoreboard_image->servers[i]; | |
res = score_record.status; | |
if (res == SERVER_READY) | |
ready++; | |
} | |
if (ready < 1) { | |
ap_log_error(__FILE__, __LINE__, APLOG_NOERRNO, r->server, "shed request from %s.", r->connection->remote_ip); | |
return HTTP_SERVICE_UNAVAILABLE; | |
} | |
} | |
return DECLINED; | |
} | |
static const command_rec loadshed_cmds[] = { | |
{"LoadShed", set_loadshed, NULL, OR_OPTIONS, FLAG, "set mod_loadshed on or off"}, | |
{NULL} | |
}; | |
module MODULE_VAR_EXPORT loadshed_module = | |
{ | |
STANDARD_MODULE_STUFF, | |
NULL, /* initializer */ | |
create_mconfig_for_directory, /* create per-dir config */ | |
NULL, /* merge per-dir config */ | |
create_mconfig_for_server, /* server config */ | |
NULL, /* merge server config */ | |
loadshed_cmds, /* command table */ | |
NULL, /* handlers */ | |
NULL, /* filename translation */ | |
NULL, /* check_user_id */ | |
NULL, /* check auth */ | |
NULL, /* check access */ | |
NULL, /* type_checker */ | |
NULL, /* fixups */ | |
NULL, /* logger */ | |
NULL, /* header parser */ | |
NULL, /* child_init */ | |
NULL, /* child_exit */ | |
check_loadshed /* post read-request */ | |
}; | |
/* eof */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment