aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2018-03-15 08:02:16 +0200
committerSergey Poznyakoff <gray@gnu.org>2018-03-15 08:02:16 +0200
commit677473cdfc42b9fd83623902e80de946f108825c (patch)
tree8b2db22aaf02ec8fcf95e9142ad490e1e26d8bdd
parent557ac31167d217b19efab8b8cfbd0a97a044a4b7 (diff)
downloadeclat-677473cdfc42b9fd83623902e80de946f108825c.tar.gz
eclat-677473cdfc42b9fd83623902e80de946f108825c.tar.bz2
Update docs
-rw-r--r--NEWS27
-rw-r--r--configure.ac4
-rw-r--r--doc/eclat.conf.533
-rw-r--r--src/config.c2
-rw-r--r--src/util.c12
5 files changed, 65 insertions, 13 deletions
diff --git a/NEWS b/NEWS
index d71f794..c7edebd 100644
--- a/NEWS
+++ b/NEWS
@@ -1,10 +1,31 @@
-Eclat NEWS -- history of user-visible changes. 2015-11-19
-Copyright (C) 2012-2015 Sergey Poznyakoff
+Eclat NEWS -- history of user-visible changes. 2018-03-15
+Copyright (C) 2012-2018 Sergey Poznyakoff
See the end of file for copying conditions.
Please send Eclat bug reports to <bug-eclat@gnu.org.ua>
-Version 1.1.90 (Git)
+Version 1.1.91 (Git)
+
+* Exponential backoff with jitter
+
+If AWS responds with a RequestLimitExceeded code, eclat retries the
+request using exponential backoff with jitter algorithm. The algorithm
+is controlled by two values: max-retry-interval and total-retry-timeout.
+When the RequestLimitExceeded error is returned, eclat will sleep for
+2 seconds and then retry the request. For each subsequent
+RequestLimitExceeded error, it will calculate the timeout using the
+following formula:
+
+ t = rand(0, min(M, 2 ** N)) + 1
+
+where N is the attempt number, M is the value of max-retry-interval
+parameter, 'rand(a,b)' selects the integer random number X such that
+0 <= X <= b, and '**' denotes power operator. The attempts to resend
+the request will continue until either a response other than
+RequestLimitExceeded is received (be it a response to the query or
+another error response), or the total time spent in the retry loop
+becomes equal to or greater than total-retry-timeout, whichever occurs
+first.
* VPC Support
diff --git a/configure.ac b/configure.ac
index a2e0cfb..1673dbb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,5 +1,5 @@
# This file is part of Eclat -*- autoconf -*-
-# Copyright (C) 2012-2015 Sergey Poznyakoff
+# Copyright (C) 2012-2018 Sergey Poznyakoff
#
# Eclat is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -15,7 +15,7 @@
# along with Eclat. If not, see <http://www.gnu.org/licenses/>.
AC_PREREQ(2.63)
-AC_INIT([eclat], 1.1.90, [bug-eclat@gnu.org.ua],,
+AC_INIT([eclat], 1.1.91, [bug-eclat@gnu.org.ua],,
[http://www.gnu.org.ua/software/eclat])
AC_CONFIG_SRCDIR([src/eclat.h])
AC_CONFIG_AUX_DIR([build-aux])
diff --git a/doc/eclat.conf.5 b/doc/eclat.conf.5
index c896dba..bc6a567 100644
--- a/doc/eclat.conf.5
+++ b/doc/eclat.conf.5
@@ -13,7 +13,7 @@
.\"
.\" You should have received a copy of the GNU General Public License
.\" along with Eclat. If not, see <http://www.gnu.org/licenses/>.
-.TH ECLAT.CONF 5 "November 19, 2015" "ECLAT" "Eclat User Reference"
+.TH ECLAT.CONF 5 "March 15, 2018" "ECLAT" "Eclat User Reference"
.SH NAME
eclat.conf \- configuration file for
.BR eclat (1).
@@ -469,6 +469,37 @@ This is a shortcut for \fBauthentication\-provider file \fIname\fR.
\fBsignature\-version\fR \fIN\fR;
Declares the signature version. Valid values for \fIN\fR are \fB2\fR,
which is the default, and \fB4\fR, which provides a better security.
+.SH RETRY ON ERRORS
+If AWS responds with a \fBRequestLimitExceeded\fR code, \fBeclat\fR
+retries the request using exponential backoff with jitter algorithm.
+The algorithm is controlled by two configuration values:
+.B max\-retry\-interval
+and
+.BR total\-retry\-timeout .
+When the \fBRequestLimitExceeded\fR error is returned, \fBeclat\fR
+will sleep for up to 2 seconds and then retry the request. For each
+subsequent \fBRequestLimitExceeded\fR error, it will calculate the
+timeout using the following formula:
+.EX
+ t = rand(0, min(M, 2 ** N)) + 1
+.EE
+where N is the attempt number, M is the value of max-retry-interval
+parameter, 'rand(a,b)' selects the integer random number X such that
+0 <= X <= b, and '**' is the power operator. The attempts to resend
+the request will continue until either a response other than
+\fBRequestLimitExceeded\fR is received (be it a response to the query or
+another error response), or the total time spent in the retry loop
+becomes equal to or greater than
+.BR total-retry-timeout ,
+whichever occurs
+first.
+.PP
+Default values are:
+.PP
+.EX
+max-retry-interval 600;
+total-retry-timeout 1800;
+.EE
.SH INSTANCE STORE CONFIGURATION
The \fBinstance\-store\fR compound statement configures HTTP access to
the instance store. By default, \fBeclat\fR uses standard AWS values.
diff --git a/src/config.c b/src/config.c
index 6fac842..069ddd0 100644
--- a/src/config.c
+++ b/src/config.c
@@ -399,7 +399,7 @@ static struct grecs_keyword eclat_kw[] = {
{ "max-retry-interval", "seconds",
"Maximum interval between retries in exponential backoff algorithm.",
grecs_type_ulong, GRECS_DFLT, &max_retry_sleep },
- { "retry-timeout", "seconds",
+ { "total-retry-timeout", "seconds",
"Give up retrying after this many seconds",
grecs_type_ulong, GRECS_DFLT, &max_retry_time },
{ "default-region", "name",
diff --git a/src/util.c b/src/util.c
index 3ada220..43b27ef 100644
--- a/src/util.c
+++ b/src/util.c
@@ -236,7 +236,7 @@ eclat_send_request(struct ec2_request *orig, struct grecs_node **ret_tree)
endtime = time(NULL) + max_retry_time;
tts = 2;
- do {
+ while (1) {
struct grecs_node *node;
struct ec2_request *req;
@@ -301,11 +301,14 @@ eclat_send_request(struct ec2_request *orig, struct grecs_node **ret_tree)
if (dry_run_mode)
debug(ECLAT_DEBCAT_MAIN, 1, ("not sending request"));
else {
+ grecs_tree_free(xmltree);
+
res = curl_easy_perform(io->curl);
if (res == CURLE_OK) {
xmltree = eclat_io_finish(io);
} else {
err("CURL: %s", curl_easy_strerror(res));
+ xmltree = NULL;
ret = 1;
}
}
@@ -314,7 +317,7 @@ eclat_send_request(struct ec2_request *orig, struct grecs_node **ret_tree)
curl_slist_free_all(headers);
eclat_request_free(req);
- if (ret)
+ if (ret || time(NULL) >= endtime)
break;
node = grecs_find_node(xmltree, ".Response.Errors.Error.Code");
@@ -329,9 +332,6 @@ eclat_send_request(struct ec2_request *orig, struct grecs_node **ret_tree)
if (strcmp(node->v.value->v.string, "RequestLimitExceeded"))
break;
- grecs_tree_free(xmltree);
- xmltree = NULL;
-
t = random() % tts + 1;
warn("request limit exceeded; sleeping for %lu seconds", t);
sleep(t);
@@ -340,7 +340,7 @@ eclat_send_request(struct ec2_request *orig, struct grecs_node **ret_tree)
if (tts == 0 || tts > max_retry_sleep)
tts = max_retry_sleep;
}
- } while (time(NULL) < endtime);
+ }
*ret_tree = xmltree;
return ret;

Return to:

Send suggestions and report system problems to the System administrator.