[MEDIUM] add support for time units in the configuration

It is not always handy to manipulate large values exprimed
in milliseconds for timeouts. Also, some values are entered
in seconds (such as the stats refresh interval). This patch
adds support for time units. It knows about 'us', 'ms', 's',
'm', 'h', and 'd'. It automatically converts each value into
the caller's expected unit. Unit-less values are still passed
unchanged.

The unit must be passed as a suffix to the number. For instance:

     clitimeout 15m

If any character is not understood, an error is returned.
This commit is contained in:
Willy Tarreau 2007-12-02 22:15:14 +01:00
parent a0d37b69ef
commit b3f32f5f8a
3 changed files with 85 additions and 14 deletions

View File

@ -513,7 +513,8 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
static struct proxy *curproxy = NULL;
struct server *newsrv = NULL;
const char *err;
int rc, val;
int rc;
unsigned val;
if (!strcmp(args[0], "listen"))
rc = PR_CAP_LISTEN;
@ -868,7 +869,12 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
curproxy->appsession_name = strdup(args[1]);
curproxy->appsession_name_len = strlen(curproxy->appsession_name);
curproxy->appsession_len = atoi(args[3]);
val = atoi(args[5]);
err = parse_time_err(args[5], &val, TIME_UNIT_MS);
if (err) {
Alert("parsing [%s:%d] : unexpected character '%c' in %s timeout.\n",
file, linenum, *err, args[0]);
return -1;
}
if (val > 0)
__tv_from_ms(&curproxy->appsession_timeout, val);
else
@ -977,7 +983,12 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
file, linenum, args[0]);
return -1;
}
val = atoi(args[1]);
err = parse_time_err(args[1], &val, TIME_UNIT_MS);
if (err) {
Alert("parsing [%s:%d] : unexpected character '%c' in %s.\n",
file, linenum, *err, args[0]);
return -1;
}
if (val > 0)
__tv_from_ms(&curproxy->contimeout, val);
else
@ -997,7 +1008,12 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
file, linenum, args[0]);
return -1;
}
val = atoi(args[1]);
err = parse_time_err(args[1], &val, TIME_UNIT_MS);
if (err) {
Alert("parsing [%s:%d] : unexpected character '%c' in %s.\n",
file, linenum, *err, args[0]);
return -1;
}
if (val > 0)
__tv_from_ms(&curproxy->clitimeout, val);
else
@ -1016,7 +1032,12 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
file, linenum, args[0]);
return -1;
}
val = atoi(args[1]);
err = parse_time_err(args[1], &val, TIME_UNIT_MS);
if (err) {
Alert("parsing [%s:%d] : unexpected character '%c' in %s.\n",
file, linenum, *err, args[0]);
return -1;
}
if (val > 0)
__tv_from_ms(&curproxy->srvtimeout, val);
else
@ -1118,10 +1139,12 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
return -1;
}
} else if (!strcmp(args[1], "refresh")) {
int interval = atoi(args[2]);
if (interval < 0) {
Alert("parsing [%s:%d] : 'refresh' needs a positive interval in seconds.\n", file, linenum);
unsigned interval;
err = parse_time_err(args[2], &interval, TIME_UNIT_S);
if (err) {
Alert("parsing [%s:%d] : unexpected character '%c' in stats refresh interval.\n",
file, linenum, *err);
return -1;
} else if (!stats_set_refresh(&curproxy->uri_auth, interval)) {
Alert("parsing [%s:%d] : out of memory.\n", file, linenum);
@ -1383,7 +1406,13 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
Alert("parsing [%s:%d] : '%s' expects a time in milliseconds.\n", file, linenum, args[0]);
return -1;
}
curproxy->grace = atol(args[1]);
err = parse_time_err(args[1], &val, TIME_UNIT_MS);
if (err) {
Alert("parsing [%s:%d] : unexpected character '%c' in grace time.\n",
file, linenum, *err);
return -1;
}
curproxy->grace = val;
}
else if (!strcmp(args[0], "dispatch")) { /* dispatch address */
if (curproxy == &defproxy) {
@ -1502,7 +1531,13 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
cur_arg += 2;
}
else if (!strcmp(args[cur_arg], "inter")) {
newsrv->inter = atol(args[cur_arg + 1]);
const char *err = parse_time_err(args[cur_arg + 1], &val, TIME_UNIT_MS);
if (err) {
Alert("parsing [%s:%d] : unexpected character '%c' in 'inter' argument of server %s.\n",
file, linenum, *err, newsrv->id);
return -1;
}
newsrv->inter = val;
cur_arg += 2;
}
else if (!strcmp(args[cur_arg], "addr")) {
@ -1542,7 +1577,13 @@ int cfg_parse_listen(const char *file, int linenum, char **args)
}
else if (!strcmp(args[cur_arg], "slowstart")) {
/* slowstart is stored in seconds */
newsrv->slowstart = (atol(args[cur_arg + 1]) + 999) / 1000;
const char *err = parse_time_err(args[cur_arg + 1], &val, TIME_UNIT_S);
if (err) {
Alert("parsing [%s:%d] : unexpected character '%c' in 'slowstart' argument of server %s.\n",
file, linenum, *err, newsrv->id);
return -1;
}
newsrv->slowstart = val;
cur_arg += 2;
}
else if (!strcmp(args[cur_arg], "check")) {

View File

@ -127,9 +127,15 @@ int stats_parse_global(const char **args, char *err, int errlen)
global.maxsock++;
}
else if (!strcmp(args[0], "timeout")) {
int timeout = atol(args[1]);
unsigned timeout;
const char *res = parse_time_err(args[1], &timeout, TIME_UNIT_MS);
if (timeout <= 0) {
if (res) {
snprintf(err, errlen, "unexpected character '%c' in 'stats timeout' in 'global' section", *res);
return -1;
}
if (!timeout) {
snprintf(err, errlen, "a positive value is expected for 'stats timeout' in 'global section'");
return -1;
}

24
tests/test-time.cfg Normal file
View File

@ -0,0 +1,24 @@
# This is a test configuration.
# It is used to check that time units are correctly parsed.
global
maxconn 1000
stats timeout 3s
listen sample1
mode http
retries 1
redispatch
contimeout 5s
clitimeout 15m
srvtimeout 15m
maxconn 40000
bind :8080
balance roundrobin
option allbackups
server act1 127.0.0.1:80 weight 10 check port 81 inter 500ms fall 1
server act2 127.0.0.2:80 weight 20 check port 81 inter 500ms fall 1
server act3 127.0.0.3:80 weight 30 check port 81 inter 500ms fall 1
option httpclose
stats uri /stats
stats refresh 5000ms