make_coin_known can experience serialization failures, add retry logic

This commit is contained in:
Christian Grothoff 2022-02-24 13:53:09 +01:00
parent 10b9023575
commit fd9ba53c49
No known key found for this signature in database
GPG Key ID: 939E6BE1E29FC3CC
4 changed files with 48 additions and 25 deletions

View File

@ -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,

View File

@ -27,6 +27,19 @@
#include <gnunet/gnunet_mhd_compat.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
/**
* Ensure coin is known in the database, and handle conflicts and errors.
*

View File

@ -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;
}

View File

@ -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;
}