summaryrefslogtreecommitdiff
path: root/src/backenddb
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2017-11-02 14:19:16 +0100
committerChristian Grothoff <christian@grothoff.org>2017-11-02 14:19:16 +0100
commitd4fe427d4974cfb0492e656dfd7217ff1b6056a8 (patch)
treec1fc948d7889727ac40fd2e67ed4b86e145c1ce5 /src/backenddb
parent73be11d78cff70e62c9afbab787dbc375c1d28ba (diff)
downloadmerchant-d4fe427d4974cfb0492e656dfd7217ff1b6056a8.tar.gz
merchant-d4fe427d4974cfb0492e656dfd7217ff1b6056a8.tar.bz2
merchant-d4fe427d4974cfb0492e656dfd7217ff1b6056a8.zip
deal with soft errors by retrying in merchantdb (for tipping)
Diffstat (limited to 'src/backenddb')
-rw-r--r--src/backenddb/plugin_merchantdb_postgres.c82
1 files changed, 55 insertions, 27 deletions
diff --git a/src/backenddb/plugin_merchantdb_postgres.c b/src/backenddb/plugin_merchantdb_postgres.c
index f15374cf..826ed698 100644
--- a/src/backenddb/plugin_merchantdb_postgres.c
+++ b/src/backenddb/plugin_merchantdb_postgres.c
@@ -28,6 +28,11 @@
#include <taler/taler_json_lib.h>
#include "taler_merchantdb_plugin.h"
+/**
+ * How often do we re-try if we run into a DB serialization error?
+ */
+#define MAX_RETRIES 3
+
/**
* Type of the "cls" argument given to each of the functions in
@@ -2631,8 +2636,13 @@ postgres_enable_tip_reserve (void *cls,
enum GNUNET_DB_QueryStatus qs;
struct GNUNET_TIME_Absolute new_expiration;
struct TALER_Amount new_balance;
+ unsigned int retries;
+ retries = 0;
check_connection (pg);
+ RETRY:
+ if (MAX_RETRIES < ++retries)
+ return GNUNET_DB_STATUS_SOFT_ERROR;
if (GNUNET_OK !=
postgres_start (pg))
{
@@ -2659,6 +2669,8 @@ postgres_enable_tip_reserve (void *cls,
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
postgres_rollback (pg);
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ goto RETRY;
return qs;
}
/* UUID already exists, we are done! */
@@ -2692,6 +2704,8 @@ postgres_enable_tip_reserve (void *cls,
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
postgres_rollback (pg);
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ goto RETRY;
return qs;
}
if ( (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs) &&
@@ -2741,6 +2755,8 @@ postgres_enable_tip_reserve (void *cls,
{
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
postgres_rollback (pg);
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ goto RETRY;
return qs;
}
}
@@ -2748,6 +2764,8 @@ postgres_enable_tip_reserve (void *cls,
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
return GNUNET_DB_STATUS_SUCCESS_ONE_RESULT;
GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR == qs);
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ goto RETRY;
return qs;
}
@@ -2797,8 +2815,13 @@ postgres_authorize_tip (void *cls,
};
enum GNUNET_DB_QueryStatus qs;
struct TALER_Amount new_balance;
+ unsigned int retries;
+ retries = 0;
check_connection (pg);
+ RETRY:
+ if (MAX_RETRIES < ++retries)
+ return TALER_EC_TIP_AUTHORIZE_DB_SOFT_ERROR;
if (GNUNET_OK !=
postgres_start (pg))
{
@@ -2813,11 +2836,11 @@ postgres_authorize_tip (void *cls,
{
/* reserve unknown */
postgres_rollback (pg);
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ goto RETRY;
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
return TALER_EC_TIP_AUTHORIZE_RESERVE_NOT_ENABLED;
- return (GNUNET_DB_STATUS_HARD_ERROR == qs)
- ? TALER_EC_TIP_AUTHORIZE_DB_HARD_ERROR
- : TALER_EC_TIP_AUTHORIZE_DB_SOFT_ERROR;
+ return TALER_EC_TIP_AUTHORIZE_DB_HARD_ERROR;
}
if (0 == GNUNET_TIME_absolute_get_remaining (old_expiration).rel_value_us)
{
@@ -2849,9 +2872,9 @@ postgres_authorize_tip (void *cls,
if (0 > qs)
{
postgres_rollback (pg);
- return (GNUNET_DB_STATUS_HARD_ERROR == qs)
- ? TALER_EC_TIP_AUTHORIZE_DB_HARD_ERROR
- : TALER_EC_TIP_AUTHORIZE_DB_SOFT_ERROR;
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ goto RETRY;
+ return TALER_EC_TIP_AUTHORIZE_DB_HARD_ERROR;
}
}
/* Generate and store tip ID */
@@ -2878,17 +2901,17 @@ postgres_authorize_tip (void *cls,
if (0 > qs)
{
postgres_rollback (pg);
- return (GNUNET_DB_STATUS_HARD_ERROR == qs)
- ? TALER_EC_TIP_AUTHORIZE_DB_HARD_ERROR
- : TALER_EC_TIP_AUTHORIZE_DB_SOFT_ERROR;
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ goto RETRY;
+ return TALER_EC_TIP_AUTHORIZE_DB_HARD_ERROR;
}
}
qs = postgres_commit (pg);
if (0 <= qs)
return TALER_EC_NONE; /* success! */
- return (GNUNET_DB_STATUS_HARD_ERROR == qs)
- ? TALER_EC_TIP_AUTHORIZE_DB_HARD_ERROR
- : TALER_EC_TIP_AUTHORIZE_DB_SOFT_ERROR;
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ goto RETRY;
+ return TALER_EC_TIP_AUTHORIZE_DB_HARD_ERROR;
}
@@ -2970,8 +2993,13 @@ postgres_pickup_tip (void *cls,
GNUNET_PQ_result_spec_end
};
enum GNUNET_DB_QueryStatus qs;
+ unsigned int retries;
+ retries = 0;
check_connection (pg);
+ RETRY:
+ if (MAX_RETRIES < ++retries)
+ return GNUNET_DB_STATUS_SOFT_ERROR;
if (GNUNET_OK !=
postgres_start (pg))
{
@@ -2991,9 +3019,9 @@ postgres_pickup_tip (void *cls,
postgres_rollback (pg);
if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
return TALER_EC_TIP_PICKUP_TIP_ID_UNKNOWN;
- return (GNUNET_DB_STATUS_HARD_ERROR == qs)
- ? TALER_EC_TIP_PICKUP_DB_ERROR_HARD
- : TALER_EC_TIP_PICKUP_DB_ERROR_SOFT;
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ goto RETRY;
+ return TALER_EC_TIP_PICKUP_DB_ERROR_HARD;
}
/* Check if pickup_id already exists */
@@ -3021,9 +3049,9 @@ postgres_pickup_tip (void *cls,
0,
sizeof (*reserve_priv));
postgres_rollback (pg);
- return (GNUNET_DB_STATUS_HARD_ERROR == qs)
- ? TALER_EC_TIP_PICKUP_DB_ERROR_HARD
- : TALER_EC_TIP_PICKUP_DB_ERROR_SOFT;
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ goto RETRY;
+ return TALER_EC_TIP_PICKUP_DB_ERROR_HARD;
}
if (GNUNET_DB_STATUS_SUCCESS_ONE_RESULT == qs)
{
@@ -3074,9 +3102,9 @@ postgres_pickup_tip (void *cls,
memset (reserve_priv,
0,
sizeof (*reserve_priv));
- return (GNUNET_DB_STATUS_HARD_ERROR == qs)
- ? TALER_EC_TIP_PICKUP_DB_ERROR_HARD
- : TALER_EC_TIP_PICKUP_DB_ERROR_SOFT;
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ goto RETRY;
+ return TALER_EC_TIP_PICKUP_DB_ERROR_HARD;
}
}
@@ -3098,18 +3126,18 @@ postgres_pickup_tip (void *cls,
memset (reserve_priv,
0,
sizeof (*reserve_priv));
- return (GNUNET_DB_STATUS_HARD_ERROR == qs)
- ? TALER_EC_TIP_PICKUP_DB_ERROR_HARD
- : TALER_EC_TIP_PICKUP_DB_ERROR_SOFT;
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ goto RETRY;
+ return TALER_EC_TIP_PICKUP_DB_ERROR_HARD;
}
}
}
qs = postgres_commit (pg);
if (0 <= qs)
return TALER_EC_NONE; /* success */
- return (GNUNET_DB_STATUS_HARD_ERROR == qs)
- ? TALER_EC_TIP_PICKUP_DB_ERROR_HARD
- : TALER_EC_TIP_PICKUP_DB_ERROR_SOFT;
+ if (GNUNET_DB_STATUS_SOFT_ERROR == qs)
+ goto RETRY;
+ return TALER_EC_TIP_PICKUP_DB_ERROR_HARD;
}