gnunet-svn
[Top][All Lists]
Advanced

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

[taler-merchant] 229/277: finish taler-merchant-httpd_reserves implement


From: gnunet
Subject: [taler-merchant] 229/277: finish taler-merchant-httpd_reserves implementation
Date: Sun, 05 Jul 2020 20:52:22 +0200

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

grothoff pushed a commit to branch master
in repository merchant.

commit c6a10b52461f7781ac3e9c6aeb467ecbd7bdad38
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Sat Jun 20 19:46:32 2020 +0200

    finish taler-merchant-httpd_reserves implementation
---
 src/backend/taler-merchant-httpd_reserves.c | 228 ++++++++++++++++++++++++++--
 1 file changed, 212 insertions(+), 16 deletions(-)

diff --git a/src/backend/taler-merchant-httpd_reserves.c 
b/src/backend/taler-merchant-httpd_reserves.c
index 5876243..1d17632 100644
--- a/src/backend/taler-merchant-httpd_reserves.c
+++ b/src/backend/taler-merchant-httpd_reserves.c
@@ -21,6 +21,7 @@
 #include "platform.h"
 #include <taler/taler_json_lib.h>
 #include "taler-merchant-httpd.h"
+#include "taler-merchant-httpd_exchanges.h"
 #include "taler-merchant-httpd_reserves.h"
 
 
@@ -29,6 +30,17 @@
  */
 struct Reserve
 {
+
+  /**
+   * Kept in a DLL.
+   */
+  struct Reserve *next;
+
+  /**
+   * Kept in a DLL.
+   */
+  struct Reserve *prev;
+
   /**
    * Reserve's public key.
    */
@@ -49,15 +61,207 @@ struct Reserve
    * Instance this reserve belongs with.
    */
   char *instance_id;
+
+  /**
+   * Active find operation for this reserve.
+   */
+  struct TMH_EXCHANGES_FindOperation *fo;
+
+  /**
+   * Task scheduled waiting for a timeout for this reserve.
+   */
+  struct GNUNET_SCHEDULER_Task *tt;
+
+  /**
+   * Get operation with the exchange.
+   */
+  struct TALER_EXCHANGE_ReservesGetHandle *gh;
+
+  /**
+   * How long do we wait before trying this reserve again?
+   */
+  struct GNUNET_TIME_Relative delay;
+
 };
 
 
+/**
+ * Head of DLL of pending reserves.
+ */
+static struct Reserve *reserves_head;
+
+/**
+ * Tail of DLL of pending reserves.
+ */
+static struct Reserve *reserves_tail;
+
+
+/**
+ * Function called to probe a reserve now.
+ *
+ * @param cls a `struct Reserve` to query
+ */
+static void
+try_now (void *cls);
+
+
+/**
+ * Free reserve data structure.
+ *
+ * @param r reserve to free
+ */
+static void
+free_reserve (struct Reserve *r)
+{
+  GNUNET_CONTAINER_DLL_remove (reserves_head,
+                               reserves_tail,
+                               r);
+  if (NULL != r->fo)
+  {
+    TMH_EXCHANGES_find_exchange_cancel (r->fo);
+    r->fo = NULL;
+  }
+  if (NULL != r->gh)
+  {
+    TALER_EXCHANGE_reserves_get_cancel (r->gh);
+    r->gh = NULL;
+  }
+  if (NULL != r->tt)
+  {
+    GNUNET_SCHEDULER_cancel (r->tt);
+    r->tt = NULL;
+  }
+  GNUNET_free (r->exchange_url);
+  GNUNET_free (r->instance_id);
+  GNUNET_free (r);
+}
+
+
+/**
+ * Schedule a job to probe a reserve later again.
+ *
+ * @param r reserve to try again later
+ */
+static void
+try_later (struct Reserve *r)
+{
+  r->delay = GNUNET_TIME_STD_BACKOFF (r->delay);
+  r->tt = GNUNET_SCHEDULER_add_delayed (r->delay,
+                                        &try_now,
+                                        r);
+}
+
+
+/**
+ * Callbacks of this type are used to serve the result of submitting a
+ * reserve status request to a exchange.
+ *
+ * @param cls closure with a `struct Reserve *`
+ * @param hr HTTP response data
+ * @param balance current balance in the reserve, NULL on error
+ * @param history_length number of entries in the transaction history, 0 on 
error
+ * @param history detailed transaction history, NULL on error
+ */
+static void
+reserve_cb (void *cls,
+            const struct TALER_EXCHANGE_HttpResponse *hr,
+            const struct TALER_Amount *balance,
+            unsigned int history_length,
+            const struct TALER_EXCHANGE_ReserveHistory *history)
+{
+  struct Reserve *r = cls;
+  enum GNUNET_DB_QueryStatus qs;
+
+  r->gh = NULL;
+  if ( (NULL == hr) ||
+       (MHD_HTTP_OK != hr->http_status) )
+  {
+    try_later (r);
+    return;
+  }
+  qs = TMH_db->activate_reserve (TMH_db->cls,
+                                 r->instance_id,
+                                 &r->reserve_pub,
+                                 balance);
+  if (qs <= 0)
+  {
+    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+                "Failed to commit reserve activation to database (%d)\n",
+                (int) qs);
+  }
+  free_reserve (r);
+}
+
+
+/**
+ * Function called with the result of a #TMH_EXCHANGES_find_exchange()
+ * operation.
+ *
+ * @param cls closure
+ * @param hr HTTP response details
+ * @param eh handle to the exchange context
+ * @param payto_uri payto://-URI of the exchange
+ * @param wire_fee current applicable wire fee for dealing with @a eh, NULL if 
not available
+ * @param exchange_trusted true if this exchange is trusted by config
+ */
+static void
+find_cb (void *cls,
+         const struct TALER_EXCHANGE_HttpResponse *hr,
+         struct TALER_EXCHANGE_Handle *eh,
+         const char *payto_uri,
+         const struct TALER_Amount *wire_fee,
+         bool exchange_trusted)
+{
+  struct Reserve *r = cls;
+
+  r->fo = NULL;
+  if (NULL == eh)
+  {
+    try_later (r);
+    return;
+  }
+  r->gh = TALER_EXCHANGE_reserves_get (eh,
+                                       &r->reserve_pub,
+                                       &reserve_cb,
+                                       r);
+  if (NULL == r->gh)
+  {
+    try_later (r);
+    return;
+  }
+}
+
+
+/**
+ * Function called to probe a reserve now.
+ *
+ * @param cls a `struct Reserve` to query
+ */
+static void
+try_now (void *cls)
+{
+  struct Reserve *r = cls;
+
+  r->tt = NULL;
+  r->fo = TMH_EXCHANGES_find_exchange (r->exchange_url,
+                                       NULL,
+                                       GNUNET_NO,
+                                       &find_cb,
+                                       r);
+  if (NULL == r->fo)
+  {
+    try_later (r);
+    return;
+  }
+}
+
+
 /**
  * Function called with information about a reserve that we need
  * to check the status from at the exchange to see if/when it has
  * been filled (and with what amount).
  *
- * @param cls closure
+ * @param cls closure, NULL
  * @param instance_id for which instance is this reserve
  * @param exchange_url base URL of the exchange at which the reserve lives
  * @param reserve_pub public key of the reserve
@@ -72,12 +276,16 @@ add_reserve (void *cls,
 {
   struct Reserve *r;
 
+  (void) cls;
   r = GNUNET_new (struct Reserve);
   r->exchange_url = GNUNET_strdup (exchange_url);
   r->instance_id = GNUNET_strdup (instance_id);
   r->reserve_pub = *reserve_pub;
   r->expected_amount = *expected_amount;
-  // ....
+  GNUNET_CONTAINER_DLL_insert (reserves_head,
+                               reserves_tail,
+                               r);
+  try_now (r);
 }
 
 
@@ -108,25 +316,11 @@ TMH_RESERVES_check (const char *instance_id,
                     const struct TALER_ReservePublicKeyP *reserve_pub,
                     const struct TALER_Amount *expected_amount)
 {
-  enum GNUNET_DB_QueryStatus qs;
-
   add_reserve (NULL,
                instance_id,
                exchange_url,
                reserve_pub,
                expected_amount);
-
-  // Do this temporarily for testing
-  qs = TMH_db->activate_reserve (TMH_db->cls,
-                                 instance_id,
-                                 reserve_pub,
-                                 expected_amount); // FIXME: change to REAL 
amount later!
-  if (qs <= 0)
-  {
-    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
-                "Failed to commit reserve activation to database (%d)\n",
-                (int) qs);
-  }
 }
 
 
@@ -136,6 +330,8 @@ TMH_RESERVES_check (const char *instance_id,
 void
 TMH_RESERVES_done (void)
 {
+  while (NULL != reserves_head)
+    free_reserve (reserves_head);
 }
 
 

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

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