aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/auditor/generate-auditor-basedb.conf1
-rw-r--r--src/exchange/exchange.conf5
-rw-r--r--src/exchange/taler-exchange-httpd.c33
3 files changed, 37 insertions, 2 deletions
diff --git a/src/auditor/generate-auditor-basedb.conf b/src/auditor/generate-auditor-basedb.conf
index 519190e97..44be7f15e 100644
--- a/src/auditor/generate-auditor-basedb.conf
+++ b/src/auditor/generate-auditor-basedb.conf
@@ -13,6 +13,7 @@ SIGNKEY_DURATION = 4 weeks
LEGAL_DURATION = 2 years
LOOKAHEAD_SIGN = 32 weeks 1 day
LOOKAHEAD_PROVIDE = 4 weeks 1 day
+MAX_REQUESTS = 2
[merchant]
SERVE = tcp
diff --git a/src/exchange/exchange.conf b/src/exchange/exchange.conf
index 7fe737b72..79b1877d9 100644
--- a/src/exchange/exchange.conf
+++ b/src/exchange/exchange.conf
@@ -21,6 +21,11 @@ REVOCATION_DIR = ${TALER_DATA_HOME}/exchange/revocations/
# Used to artifically reduce caching (addresses #5747).
MAX_KEYS_CACHING = forever
+# After how many requests should the exchange auto-restart
+# (to address potential issues with memory fragmentation)?
+# If this option is not specified, auto-restarting is disabled.
+# MAX_REQUESTS = 10000000
+
# How to access our database
DB = postgres
diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c
index 30efb8bc2..bcac62ce9 100644
--- a/src/exchange/taler-exchange-httpd.c
+++ b/src/exchange/taler-exchange-httpd.c
@@ -1,6 +1,6 @@
/*
This file is part of TALER
- Copyright (C) 2014, 2015, 2016, 2019 Inria and GNUnet e.V.
+ Copyright (C) 2014, 2015, 2016, 2019 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software
@@ -13,7 +13,6 @@
You should have received a copy of the GNU Affero General Public License along with
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-
/**
* @file taler-exchange-httpd.c
* @brief Serve the HTTP interface of the exchange
@@ -144,6 +143,16 @@ static char *serve_unixpath;
*/
static mode_t unixpath_mode;
+/**
+ * Counter for the number of requests this HTTP has processed so far.
+ */
+static unsigned long long req_count;
+
+/**
+ * Limit for the number of requests this HTTP may process before restarting.
+ */
+static unsigned long long req_max;
+
/**
* Function called whenever MHD is done with a request. If the
@@ -422,7 +431,19 @@ handle_mhd_request (void *cls,
(void) version;
if (NULL == ecls)
{
+ unsigned long long cnt;
+
GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Handling new request\n");
+ cnt = __sync_add_and_fetch (&req_count, 1LLU);
+ if (req_max == cnt)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_INFO,
+ "Restarting exchange service after %llu requests\n",
+ cnt);
+ (void) kill (getpid (),
+ SIGHUP);
+ }
+
/* We're in a new async scope! */
ecls = *con_cls = GNUNET_new (struct ExchangeHttpRequestClosure);
GNUNET_async_scope_fresh (&ecls->async_scope_id);
@@ -498,6 +519,14 @@ exchange_serve_process_config ()
char *TEH_master_public_key_str;
if (GNUNET_OK !=
+ GNUNET_CONFIGURATION_get_value_number (cfg,
+ "exchange",
+ "MAX_REQUESTS",
+ &req_max))
+ {
+ req_max = ULONG_LONG_MAX;
+ }
+ if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_time (cfg,
"exchange",
"MAX_KEYS_CACHING",