gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] [taler-merchant] branch master updated: fix #5010 for /trac


From: gnunet
Subject: [GNUnet-SVN] [taler-merchant] branch master updated: fix #5010 for /track/transfer
Date: Thu, 29 Jun 2017 18:54:11 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository merchant.

The following commit(s) were added to refs/heads/master by this push:
     new 515e970  fix #5010 for /track/transfer
515e970 is described below

commit 515e970f6d6104a63ed7cdb47b9c7ea28794c9ef
Author: Christian Grothoff <address@hidden>
AuthorDate: Thu Jun 29 18:54:04 2017 +0200

    fix #5010 for /track/transfer
---
 src/backend/taler-merchant-httpd_track-transfer.c | 118 ++++++++++++++--------
 1 file changed, 77 insertions(+), 41 deletions(-)

diff --git a/src/backend/taler-merchant-httpd_track-transfer.c 
b/src/backend/taler-merchant-httpd_track-transfer.c
index 71fdda4..d38cb66 100644
--- a/src/backend/taler-merchant-httpd_track-transfer.c
+++ b/src/backend/taler-merchant-httpd_track-transfer.c
@@ -1,6 +1,6 @@
 /*
   This file is part of TALER
-  (C) 2014, 2015, 2016 INRIA
+  (C) 2014-2017 INRIA
 
   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
@@ -37,6 +37,10 @@
  */
 #define TRACK_TIMEOUT (GNUNET_TIME_relative_multiply 
(GNUNET_TIME_UNIT_SECONDS, 30))
 
+/**
+ * How often do we retry the simple INSERT database transaction?
+ */
+#define MAX_RETRIES 3
 
 /**
  * Context used for handing /track/transfer requests.
@@ -307,8 +311,9 @@ transform_response (const json_t *result,
     GNUNET_CRYPTO_hash_from_string (key,
                                     &h_key);
 
-    if (NULL != (current_entry = GNUNET_CONTAINER_multihashmap_get (map,
-                                                                    &h_key)))
+    if (NULL != (current_entry =
+                GNUNET_CONTAINER_multihashmap_get (map,
+                                                   &h_key)))
     {
       /* The map already knows this h_contract_terms*/
       if ( (GNUNET_SYSERR ==
@@ -496,8 +501,8 @@ wire_transfer_cb (void *cls,
                   const struct TALER_TrackTransferDetails *details)
 {
   struct TrackTransferContext *rctx = cls;
-  int ret;
   json_t *jresponse;
+  enum GNUNET_DB_QueryStatus qs;
 
   rctx->wdh = NULL;
   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -515,17 +520,23 @@ wire_transfer_cb (void *cls,
                                     "details", json));
     return;
   }
-
-  if (GNUNET_OK !=
-      db->store_transfer_to_proof (db->cls,
-                                   rctx->uri,
-                                   &rctx->wtid,
-                                   execution_time,
-                                   exchange_pub,
-                                   json))
+  for (unsigned int i=0;i<MAX_RETRIES;i++)
+  {
+    qs = db->store_transfer_to_proof (db->cls,
+                                     rctx->uri,
+                                     &rctx->wtid,
+                                     execution_time,
+                                     exchange_pub,
+                                     json);
+    if (GNUNET_DB_STATUS_SOFT_ERROR != qs)
+      break;
+  }
+  if (0 > qs)
   {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Failed to persist wire transfer proof in DB\n");
+    /* Special report if retries insufficient */
+    GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs);
+    /* Always report on hard error as well to enable diagnostics */
+    GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
     resume_track_transfer_with_response
       (rctx,
        MHD_HTTP_INTERNAL_SERVER_ERROR,
@@ -540,16 +551,19 @@ wire_transfer_cb (void *cls,
     rctx->current_offset = i;
     rctx->current_detail = &details[i];
     rctx->check_transfer_result = GNUNET_NO;
-    ret = db->find_payments_by_hash_and_coin (db->cls,
-                                              &details[i].h_contract_terms,
-                                              &rctx->mi->pubkey,
-                                              &details[i].coin_pub,
-                                              &check_transfer,
-                                              rctx);
-    if (GNUNET_SYSERR == ret)
+    qs = db->find_payments_by_hash_and_coin (db->cls,
+                                            &details[i].h_contract_terms,
+                                            &rctx->mi->pubkey,
+                                            &details[i].coin_pub,
+                                            &check_transfer,
+                                            rctx);
+    if (0 > qs)
     {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Failed to obtain existing payment data from DB\n");
+      /* single, read-only SQL statements should never cause
+        serialization problems */
+      GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs);
+      /* Always report on hard error as well to enable diagnostics */
+      GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
       resume_track_transfer_with_response
         (rctx,
          MHD_HTTP_INTERNAL_SERVER_ERROR,
@@ -558,7 +572,7 @@ wire_transfer_cb (void *cls,
                                       "details", "failed to obtain deposit 
data from local database"));
       return;
     }
-    if (GNUNET_NO == ret)
+    if (GNUNET_DB_STATUS_SUCCESS_NO_RESULTS == qs)
     {
       /* The exchange says we made this deposit, but WE do not
          recall making it! Well, let's say thanks and accept the
@@ -596,14 +610,21 @@ wire_transfer_cb (void *cls,
     }
     /* Response is consistent with the /deposit we made, remember
        it for future reference */
-    ret = db->store_coin_to_transfer (db->cls,
-                                      &details[i].h_contract_terms,
-                                      &details[i].coin_pub,
-                                      &rctx->wtid);
-    if (GNUNET_OK != ret)
+    for (unsigned int i=0;i<MAX_RETRIES;i++)
+    {
+      qs = db->store_coin_to_transfer (db->cls,
+                                      &details[i].h_contract_terms,
+                                      &details[i].coin_pub,
+                                      &rctx->wtid);
+      if (GNUNET_DB_STATUS_SOFT_ERROR != qs)
+       break;
+    }
+    if (0 > qs)
     {
-      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                  "Failed to persist coin to wire transfer mapping in DB\n");
+      /* Special report if retries insufficient */
+      GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs);
+      /* Always report on hard error as well to enable diagnostics */
+      GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
       resume_track_transfer_with_response
         (rctx,
          MHD_HTTP_INTERNAL_SERVER_ERROR,
@@ -618,7 +639,9 @@ wire_transfer_cb (void *cls,
   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
               "About to call tracks transformator.\n");
 
-  if (NULL == (jresponse = transform_response (json, rctx)))
+  if (NULL == (jresponse =
+              transform_response (json,
+                                  rctx)))
   {
     resume_track_transfer_with_response
       (rctx,
@@ -712,12 +735,14 @@ proof_cb (void *cls,
   struct TrackTransferContext *rctx = cls;
   json_t *transformed_response;
 
-  if (NULL == (transformed_response = transform_response (proof,
-                                                          rctx)))
+  if (NULL == (transformed_response =
+              transform_response (proof,
+                                  rctx)))
   {
     rctx->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
-    rctx->response = TMH_RESPONSE_make_internal_error 
(TALER_EC_TRACK_TRANSFER_JSON_RESPONSE_ERROR,
-                                                       "Fail to elaborate 
response.");
+    rctx->response
+      = TMH_RESPONSE_make_internal_error 
(TALER_EC_TRACK_TRANSFER_JSON_RESPONSE_ERROR,
+                                         "Fail to elaborate response.");
     return;
   }
 
@@ -751,6 +776,7 @@ MH_handler_track_transfer (struct TMH_RequestHandler *rh,
   const char *uri;
   const char *instance_str;
   int ret;
+  enum GNUNET_DB_QueryStatus qs;
 
   if (NULL == *connection_cls)
   {
@@ -835,11 +861,21 @@ MH_handler_track_transfer (struct TMH_RequestHandler *rh,
   }
 
   /* Check if reply is already in database! */
-  ret = db->find_proof_by_wtid (db->cls,
-                                rctx->uri,
-                                &rctx->wtid,
-                                &proof_cb,
-                                rctx);
+  qs = db->find_proof_by_wtid (db->cls,
+                              rctx->uri,
+                              &rctx->wtid,
+                              &proof_cb,
+                              rctx);
+  if (0 > qs)
+  {
+    /* Simple select queries should not cause serialization issues */
+    GNUNET_break (GNUNET_DB_STATUS_SOFT_ERROR != qs);
+    /* Always report on hard error as well to enable diagnostics */
+    GNUNET_break (GNUNET_DB_STATUS_HARD_ERROR == qs);
+    return TMH_RESPONSE_reply_internal_error (connection,
+                                             
TALER_EC_TRACK_TRANSFER_DB_FETCH_FAILED,
+                                             "Fail to query database about 
proofs");   
+  }
   if (0 != rctx->response_code)
   {
     ret = MHD_queue_response (connection,

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

[Prev in Thread] Current Thread [Next in Thread]