From 5d3bfab13a189a5f8a94ccadf257a6a612e618dc Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 21 Jun 2020 23:52:30 +0200 Subject: add missing notifications to private-get-orders long poller --- .../taler-merchant-httpd_private-get-orders.c | 82 +++++++++------------- 1 file changed, 34 insertions(+), 48 deletions(-) (limited to 'src/backend/taler-merchant-httpd_private-get-orders.c') diff --git a/src/backend/taler-merchant-httpd_private-get-orders.c b/src/backend/taler-merchant-httpd_private-get-orders.c index d2f502f9..05d518f5 100644 --- a/src/backend/taler-merchant-httpd_private-get-orders.c +++ b/src/backend/taler-merchant-httpd_private-get-orders.c @@ -25,18 +25,18 @@ /** * A pending GET /orders request that is in long polling mode. */ -struct PendingOrder +struct TMH_PendingOrder { /** * Kept in a DLL. */ - struct PendingOrder *prev; + struct TMH_PendingOrder *prev; /** * Kept in a DLL. */ - struct PendingOrder *next; + struct TMH_PendingOrder *next; /** * Which connection was suspended. @@ -49,9 +49,10 @@ struct PendingOrder struct GNUNET_CONTAINER_HeapNode *hn; /** - * Which instance is this client polling? + * Which instance is this client polling? This also defines + * which DLL this struct is part of. */ - char *instance_id; + struct TMH_MerchantInstance *mi; /** * At what time does this request expire? If set in the future, we @@ -61,7 +62,7 @@ struct PendingOrder /** * Array where we append matching orders. Must be - * json_decref()'ed when done with the `struct PendingOrder`! + * json_decref()'ed when done with the `struct TMH_PendingOrder`! */ json_t *pa; @@ -72,16 +73,6 @@ struct PendingOrder }; -/** - * Head of DLL of long-polling GET /orders requests. - */ -static struct PendingOrder *po_head; - -/** - * Tail of DLL of long-polling GET /orders requests. - */ -static struct PendingOrder *po_tail; - /** * Task to timeout pending orders. */ @@ -94,23 +85,25 @@ static struct GNUNET_CONTAINER_Heap *order_timeout_heap; /** - * We are shutting down, force resume of all GET /orders requests. + * We are shutting down (or an instance is being deleted), force resume of all + * GET /orders requests. + * + * @param mi instance to force resuming for */ void -TMH_force_get_orders_resume () +TMH_force_get_orders_resume (struct TMH_MerchantInstance *mi) { - struct PendingOrder *po; + struct TMH_PendingOrder *po; - while (NULL != (po = po_head)) + while (NULL != (po = mi->po_head)) { - GNUNET_CONTAINER_DLL_remove (po_head, - po_tail, + GNUNET_CONTAINER_DLL_remove (mi->po_head, + mi->po_tail, po); GNUNET_assert (po == GNUNET_CONTAINER_heap_remove_root (order_timeout_heap)); MHD_resume_connection (po->con); json_decref (po->pa); - GNUNET_free (po->instance_id); GNUNET_free (po); } if (NULL != order_timeout_task) @@ -134,7 +127,8 @@ TMH_force_get_orders_resume () static void order_timeout (void *cls) { - struct PendingOrder *po; + struct TMH_PendingOrder *po; + struct TMH_MerchantInstance *mi; (void) cls; order_timeout_task = NULL; @@ -157,13 +151,13 @@ order_timeout (void *cls) po->hn = NULL; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Resuming long polled job due to timeout\n"); - GNUNET_CONTAINER_DLL_remove (po_head, - po_tail, + mi = po->mi; + GNUNET_CONTAINER_DLL_remove (mi->po_head, + mi->po_tail, po); json_decref (po->pa); MHD_resume_connection (po->con); TMH_trigger_daemon (); /* we resumed, kick MHD */ - GNUNET_free (po->instance_id); GNUNET_free (po); } order_timeout_task = GNUNET_SCHEDULER_add_at (po->long_poll_timeout, @@ -221,21 +215,16 @@ add_order (void *cls, * There has been a change or addition of a new @a order_id. Wake up * long-polling clients that may have been waiting for this event. * - * FIXME: Here we go over all long polling clients. We should consider moving - * the global DLL into the *instance* data structure (note: that has then - * implications in case an instance is deleted, i.e. we would then need to - * trigger all the long pollers!). - * - * @param instance_id the instance where the order changed + * @param mi the instance where the order changed * @param order_id the order that changed * @param paid is the order paid by the customer? * @param refunded was the order refunded? * @param wire was the merchant paid via wire transfer? - * @param data execution date of the order + * @param date execution date of the order * @param order_serial_id serial ID of the order in the database */ void -TMH_notify_order_change (const char *instance_id, +TMH_notify_order_change (struct TMH_MerchantInstance *mi, const char *order_id, bool paid, bool refunded, @@ -243,9 +232,9 @@ TMH_notify_order_change (const char *instance_id, struct GNUNET_TIME_Absolute date, uint64_t order_serial_id) { - struct PendingOrder *pn; + struct TMH_PendingOrder *pn; - for (struct PendingOrder *po = po_head; + for (struct TMH_PendingOrder *po = mi->po_head; NULL != po; po = pn) { @@ -257,9 +246,6 @@ TMH_notify_order_change (const char *instance_id, ( ((TALER_EXCHANGE_YNA_YES == po->of.wired) == wired) || (TALER_EXCHANGE_YNA_ALL == po->of.wired) ) ) ) continue; - if (0 != strcmp (instance_id, - po->instance_id)) - continue; if (po->of.delta > 0) { if (order_serial_id < po->of.start_row) @@ -280,15 +266,14 @@ TMH_notify_order_change (const char *instance_id, order_id, order_serial_id, date); - GNUNET_CONTAINER_DLL_remove (po_head, - po_tail, + GNUNET_CONTAINER_DLL_remove (mi->po_head, + mi->po_tail, po); GNUNET_assert (po == GNUNET_CONTAINER_heap_remove_node (po->hn)); MHD_resume_connection (po->con); TMH_trigger_daemon (); /* we resumed, kick MHD */ json_decref (po->pa); - GNUNET_free (po->instance_id); GNUNET_free (po); } } @@ -471,7 +456,8 @@ TMH_private_get_orders (const struct TMH_RequestHandler *rh, if ( (0 == qs) && (of.timeout.rel_value_us > 0) ) { - struct PendingOrder *po; + struct TMH_MerchantInstance *mi = hc->instance; + struct TMH_PendingOrder *po; /* setup timeout heap (if not yet exists) */ if (NULL == order_timeout_heap) @@ -479,8 +465,8 @@ TMH_private_get_orders (const struct TMH_RequestHandler *rh, = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); hc->ctx = pa; hc->cc = &json_cleanup; - po = GNUNET_new (struct PendingOrder); - po->instance_id = GNUNET_strdup (hc->instance->settings.id); + po = GNUNET_new (struct TMH_PendingOrder); + po->mi = mi; po->con = connection; po->pa = json_incref (pa); po->hn = GNUNET_CONTAINER_heap_insert (order_timeout_heap, @@ -488,8 +474,8 @@ TMH_private_get_orders (const struct TMH_RequestHandler *rh, po->long_poll_timeout.abs_value_us); po->long_poll_timeout = GNUNET_TIME_relative_to_absolute (of.timeout); po->of = of; - GNUNET_CONTAINER_DLL_insert (po_head, - po_tail, + GNUNET_CONTAINER_DLL_insert (mi->po_head, + mi->po_tail, po); MHD_suspend_connection (connection); /* start timeout task */ -- cgit v1.2.3