summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2021-08-26 17:53:21 +0200
committerChristian Grothoff <christian@grothoff.org>2021-08-26 17:53:21 +0200
commit34c9a75a8f95cc5b3b63573fd998b83064ebafd4 (patch)
treed93c95dbe930b0a48773c7f86eb71da6cf7eea3f
parent25e3c3d4cbca8ecaf1625b1add41d6b030e1091a (diff)
downloadanastasis-gtk-34c9a75a8f95cc5b3b63573fd998b83064ebafd4.tar.gz
anastasis-gtk-34c9a75a8f95cc5b3b63573fd998b83064ebafd4.tar.bz2
anastasis-gtk-34c9a75a8f95cc5b3b63573fd998b83064ebafd4.zip
add long poll task support for async external challenges
-rw-r--r--src/anastasis/anastasis-gtk.c28
-rw-r--r--src/anastasis/anastasis-gtk.h19
-rw-r--r--src/anastasis/anastasis-gtk_action.c120
-rw-r--r--src/anastasis/anastasis-gtk_helper.c1
4 files changed, 164 insertions, 4 deletions
diff --git a/src/anastasis/anastasis-gtk.c b/src/anastasis/anastasis-gtk.c
index 4023b16..3a1e5e5 100644
--- a/src/anastasis/anastasis-gtk.c
+++ b/src/anastasis/anastasis-gtk.c
@@ -61,6 +61,17 @@ static struct GNUNET_CURL_Context *ctx;
struct ANASTASIS_ReduxAction *AG_ra;
/**
+ * Handle to an ongoing background action.
+ */
+struct ANASTASIS_ReduxAction *AG_long_action;
+
+/**
+ * Handle to task to reschedule #AG_long_action.
+ */
+struct GNUNET_SCHEDULER_Task *AG_long_task;
+
+
+/**
* Actual state.
*/
json_t *AG_redux_state;
@@ -143,6 +154,22 @@ anastasis_gtk_animation_activate_cb (GtkMenuItem *menuitem,
}
+void
+AG_stop_long_action (void)
+{
+ if (NULL != AG_long_action)
+ {
+ ANASTASIS_redux_action_cancel (AG_long_action);
+ AG_long_action = NULL;
+ }
+ if (NULL != AG_long_task)
+ {
+ GNUNET_SCHEDULER_cancel (AG_long_task);
+ AG_long_task = NULL;
+ }
+}
+
+
/**
* Task run on shutdown.
*
@@ -160,6 +187,7 @@ shutdown_task (void *cls)
ANASTASIS_redux_action_cancel (AG_ra);
AG_ra = NULL;
}
+ AG_stop_long_action ();
if (NULL != ctx)
{
GNUNET_CURL_fini (ctx);
diff --git a/src/anastasis/anastasis-gtk.h b/src/anastasis/anastasis-gtk.h
index a4672a8..27d23f3 100644
--- a/src/anastasis/anastasis-gtk.h
+++ b/src/anastasis/anastasis-gtk.h
@@ -56,6 +56,25 @@ extern json_t *AG_redux_state;
*/
extern struct ANASTASIS_ReduxAction *AG_ra;
+/**
+ * Handle to an ongoing background action.
+ */
+extern struct ANASTASIS_ReduxAction *AG_long_action;
+
+/**
+ * Handle to task to reschedule #AG_long_action.
+ */
+extern struct GNUNET_SCHEDULER_Task *AG_long_task;
+
+
+/**
+ * Stop long polling action in the background.
+ * Should be called whenever we leave the
+ * challenge-selecting state.
+ */
+void
+AG_stop_long_action (void);
+
/**
* Load #AG_redux_state from @a filename.
diff --git a/src/anastasis/anastasis-gtk_action.c b/src/anastasis/anastasis-gtk_action.c
index 6d2bdb9..984fef5 100644
--- a/src/anastasis/anastasis-gtk_action.c
+++ b/src/anastasis/anastasis-gtk_action.c
@@ -37,6 +37,17 @@
/**
+ * After how long does our long-poller time out?
+ */
+#define LP_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 5)
+
+/**
+ * Next time we schedule the #long_task.
+ */
+static struct GNUNET_TIME_Absolute long_next;
+
+
+/**
* Are we currently processing an action?
*/
bool AG_in_action;
@@ -2197,7 +2208,92 @@ action_secret_selecting (void)
/**
- * FIXME.
+ * Function called with the results of #ANASTASIS_redux_action on "poll".
+ *
+ * @param cls closure, NULL
+ * @param error_code Error code
+ * @param response new state as result or config information of a provider
+ */
+static void
+long_action_cb (void *cls,
+ enum TALER_ErrorCode error_code,
+ json_t *response);
+
+
+/**
+ * Schedules the 'poll' action.
+ *
+ * @param cls NULL
+ */
+static void
+long_task (void *cls)
+{
+ json_t *tspec;
+
+ (void) cls;
+ AG_long_task = NULL;
+ if (GNUNET_TIME_absolute_is_future (long_next))
+ {
+ AG_long_task = GNUNET_SCHEDULER_add_at (long_next,
+ &long_task,
+ NULL);
+ return;
+ }
+ long_next = GNUNET_TIME_relative_to_absolute (LP_TIMEOUT);
+ tspec = GNUNET_JSON_PACK (
+ GNUNET_JSON_pack_time_rel ("timeout",
+ LP_TIMEOUT));
+ AG_long_action
+ = ANASTASIS_redux_action (AG_redux_state,
+ "poll",
+ tspec,
+ &long_action_cb,
+ NULL);
+ json_decref (tspec);
+}
+
+
+/**
+ * Function called with the results of #ANASTASIS_redux_action on "poll".
+ *
+ * @param cls closure, NULL
+ * @param error_code Error code
+ * @param response new state as result or config information of a provider
+ */
+static void
+long_action_cb (void *cls,
+ enum TALER_ErrorCode error_code,
+ json_t *response)
+{
+ AG_long_action = NULL;
+ switch (error_code)
+ {
+ case TALER_EC_NONE:
+ /* continued below */
+ break;
+ default:
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "'poll' action failed: %s\n",
+ TALER_ErrorCode_get_hint (error_code));
+ /* simply try again */
+ AG_long_task = GNUNET_SCHEDULER_add_now (&long_task,
+ NULL);
+ return;
+ }
+ if (NULL != AG_ra)
+ {
+ GNUNET_break (0);
+ ANASTASIS_redux_action_cancel (AG_ra);
+ }
+ AG_action_cb (NULL,
+ TALER_EC_NONE,
+ response);
+}
+
+
+/**
+ * The user must select the next challenge to solve
+ * during the recovery process.
*/
static void
action_challenge_selecting (void)
@@ -2225,6 +2321,7 @@ action_challenge_selecting (void)
const char *type;
const char *uuid;
struct TALER_Amount cost;
+ bool async = false;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_string ("instructions",
&instructions),
@@ -2234,6 +2331,9 @@ action_challenge_selecting (void)
&provider),
GNUNET_JSON_spec_string ("uuid",
&uuid),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_bool ("async",
+ &async)),
GNUNET_JSON_spec_end ()
};
@@ -2266,7 +2366,14 @@ action_challenge_selecting (void)
uuid,
NULL))
continue;
-
+ if (async &&
+ (NULL == AG_long_task) )
+ {
+ long_next = GNUNET_TIME_UNIT_ZERO_ABS;
+ AG_long_task
+ = GNUNET_SCHEDULER_add_now (&long_task,
+ NULL);
+ }
gtk_list_store_insert_with_values (
ls,
NULL,
@@ -2436,6 +2543,10 @@ action_challenge_selecting (void)
}
+/**
+ * An Anastasis provider requires payment for a challenge.
+ * Give opportunity to the user to pay.
+ */
static void
action_challenge_paying (void)
{
@@ -3015,7 +3126,8 @@ action_challenge_solving (void)
/**
- * FIXME.
+ * The recovery process was finished. Show the recovered secret to the
+ * user.
*/
static void
action_recovery_finished (void)
@@ -3187,11 +3299,11 @@ AG_action_cb (void *cls,
GNUNET_break (0);
return;
}
-
}
else
{
json_decref (AG_redux_state);
+ AG_stop_long_action ();
AG_redux_state = json_incref (response);
}
if ( (TALER_EC_ANASTASIS_TRUTH_UNKNOWN == error_code) ||
diff --git a/src/anastasis/anastasis-gtk_helper.c b/src/anastasis/anastasis-gtk_helper.c
index 5760f00..558eb20 100644
--- a/src/anastasis/anastasis-gtk_helper.c
+++ b/src/anastasis/anastasis-gtk_helper.c
@@ -49,6 +49,7 @@ void
AG_freeze ()
{
AG_insensitive ("anastasis_gtk_main_window");
+ AG_stop_long_action ();
GNUNET_assert (NULL == AG_ra);
}