diff options
author | Christian Grothoff <christian@grothoff.org> | 2022-02-24 13:53:09 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2022-02-24 13:53:19 +0100 |
commit | fd9ba53c492835b52bd75a5ae113b7bcc81fe161 (patch) | |
tree | ccb61b10436e0fdc5cb068595fad26e910bdabb2 | |
parent | 10b9023575b14e581cfd952b75039e71488f5a8f (diff) |
make_coin_known can experience serialization failures, add retry logic
-rw-r--r-- | src/exchange/taler-exchange-httpd_db.c | 13 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_db.h | 13 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_deposit.c | 24 | ||||
-rw-r--r-- | src/exchange/taler-exchange-httpd_melt.c | 23 |
4 files changed, 48 insertions, 25 deletions
diff --git a/src/exchange/taler-exchange-httpd_db.c b/src/exchange/taler-exchange-httpd_db.c index f621d8c87..d383c471d 100644 --- a/src/exchange/taler-exchange-httpd_db.c +++ b/src/exchange/taler-exchange-httpd_db.c @@ -29,19 +29,6 @@ #include "taler-exchange-httpd_responses.h" -/** - * How often should we retry a transaction before giving up - * (for transactions resulting in serialization/dead locks only). - * - * The current value is likely too high for production. We might want to - * benchmark good values once we have a good database setup. The code is - * expected to work correctly with any positive value, albeit inefficiently if - * we too aggressively force clients to retry the HTTP request merely because - * we have database serialization issues. - */ -#define MAX_TRANSACTION_COMMIT_RETRIES 100 - - enum GNUNET_DB_QueryStatus TEH_make_coin_known (const struct TALER_CoinPublicInfo *coin, struct MHD_Connection *connection, diff --git a/src/exchange/taler-exchange-httpd_db.h b/src/exchange/taler-exchange-httpd_db.h index 7c954ffe1..bca97cf0a 100644 --- a/src/exchange/taler-exchange-httpd_db.h +++ b/src/exchange/taler-exchange-httpd_db.h @@ -28,6 +28,19 @@ /** + * How often should we retry a transaction before giving up + * (for transactions resulting in serialization/dead locks only). + * + * The current value is likely too high for production. We might want to + * benchmark good values once we have a good database setup. The code is + * expected to work correctly with any positive value, albeit inefficiently if + * we too aggressively force clients to retry the HTTP request merely because + * we have database serialization issues. + */ +#define MAX_TRANSACTION_COMMIT_RETRIES 100 + + +/** * Ensure coin is known in the database, and handle conflicts and errors. * * @param coin the coin to make known diff --git a/src/exchange/taler-exchange-httpd_deposit.c b/src/exchange/taler-exchange-httpd_deposit.c index ea319f23a..66cbe04ca 100644 --- a/src/exchange/taler-exchange-httpd_deposit.c +++ b/src/exchange/taler-exchange-httpd_deposit.c @@ -442,12 +442,24 @@ TEH_handler_deposit (struct MHD_Connection *connection, enum GNUNET_DB_QueryStatus qs; /* make sure coin is 'known' in database */ - qs = TEH_make_coin_known (&deposit.coin, - connection, - &dc.known_coin_id, - &mhd_ret); - /* no transaction => no serialization failures should be possible */ - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs); + for (unsigned int tries = 0; tries<MAX_TRANSACTION_COMMIT_RETRIES; tries++) + { + qs = TEH_make_coin_known (&deposit.coin, + connection, + &dc.known_coin_id, + &mhd_ret); + /* no transaction => no serialization failures should be possible */ + if (GNUNET_DB_STATUS_SOFT_ERROR != qs) + break; + } + if (GNUNET_DB_STATUS_SOFT_ERROR == qs) + { + GNUNET_break (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_COMMIT_FAILED, + "make_coin_known"); + } if (qs < 0) return mhd_ret; } diff --git a/src/exchange/taler-exchange-httpd_melt.c b/src/exchange/taler-exchange-httpd_melt.c index 049fd09a0..4db1b2469 100644 --- a/src/exchange/taler-exchange-httpd_melt.c +++ b/src/exchange/taler-exchange-httpd_melt.c @@ -237,12 +237,23 @@ database_melt (struct MHD_Connection *connection, MHD_RESULT mhd_ret = MHD_NO; enum GNUNET_DB_QueryStatus qs; - qs = TEH_make_coin_known (&rmc->refresh_session.coin, - connection, - &rmc->known_coin_id, - &mhd_ret); - /* no transaction => no serialization failures should be possible */ - GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs); + for (unsigned int tries = 0; tries<MAX_TRANSACTION_COMMIT_RETRIES; tries++) + { + qs = TEH_make_coin_known (&rmc->refresh_session.coin, + connection, + &rmc->known_coin_id, + &mhd_ret); + if (GNUNET_DB_STATUS_SOFT_ERROR != qs) + break; + } + if (GNUNET_DB_STATUS_SOFT_ERROR == qs) + { + GNUNET_break (0); + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_COMMIT_FAILED, + "make_coin_known"); + } if (qs < 0) return mhd_ret; } |