From e77ccd03906bd2db068136bb383976f714b3289e Mon Sep 17 00:00:00 2001 From: Marcello Stanisci Date: Wed, 15 Jan 2020 12:34:54 +0100 Subject: [PATCH] Preflight checks: put preflight check inside exchangedb start() function, and provide a preflight method for auditordb. --- src/auditor/taler-auditor-httpd.c | 4 +- src/auditor/taler-auditor-httpd_db.c | 1 - src/auditordb/plugin_auditordb_postgres.c | 41 +++++++++++++++++++++ src/exchangedb/plugin_exchangedb_postgres.c | 18 ++++++++- 4 files changed, 59 insertions(+), 5 deletions(-) diff --git a/src/auditor/taler-auditor-httpd.c b/src/auditor/taler-auditor-httpd.c index 55a343776..0acd8d8bd 100644 --- a/src/auditor/taler-auditor-httpd.c +++ b/src/auditor/taler-auditor-httpd.c @@ -372,8 +372,8 @@ handle_mhd_request (void *cls, { "/version", MHD_HTTP_METHOD_GET, "application/json", NULL, 0, &handle_version, MHD_HTTP_OK }, - /* Landing page, for now tells humans to go away (FIXME: replace - with auditor's welcome page!) */ + /* Landing page, for now tells humans to go away + * (NOTE: ideally, the reverse proxy will respond with a nicer page) */ { "/", MHD_HTTP_METHOD_GET, "text/plain", "Hello, I'm the Taler auditor. This HTTP server is not for humans.\n", 0, &TAH_MHD_handler_static_response, MHD_HTTP_OK }, diff --git a/src/auditor/taler-auditor-httpd_db.c b/src/auditor/taler-auditor-httpd_db.c index 3433e9a9f..ba40ff808 100644 --- a/src/auditor/taler-auditor-httpd_db.c +++ b/src/auditor/taler-auditor-httpd_db.c @@ -70,7 +70,6 @@ TAH_DB_run_transaction (struct MHD_Connection *connection, "failed to establish session with database"); return GNUNET_SYSERR; } - // TAH_plugin->preflight (TAH_plugin->cls, session); // FIXME: needed? for (unsigned int retries = 0; retries < MAX_TRANSACTION_COMMIT_RETRIES; retries++) { diff --git a/src/auditordb/plugin_auditordb_postgres.c b/src/auditordb/plugin_auditordb_postgres.c index 7360258ad..0d16011fc 100644 --- a/src/auditordb/plugin_auditordb_postgres.c +++ b/src/auditordb/plugin_auditordb_postgres.c @@ -62,6 +62,8 @@ struct TALER_AUDITORDB_Session * Postgres connection handle. */ struct GNUNET_PQ_Context *conn; + + const char *transaction_name; }; @@ -1012,6 +1014,43 @@ postgres_get_session (void *cls) return session; } +/** + * Do a pre-flight check that we are not in an uncommitted transaction. + * If we are, try to commit the previous transaction and output a warning. + * Does not return anything, as we will continue regardless of the outcome. + * + * @param cls the `struct PostgresClosure` with the plugin-specific state + * @param session the database connection + */ +static void +postgres_preflight (void *cls, + struct TALER_AUDITORDB_Session *session) +{ + struct GNUNET_PQ_ExecuteStatement es[] = { + GNUNET_PQ_make_execute ("ROLLBACK"), + GNUNET_PQ_EXECUTE_STATEMENT_END + }; + + (void) cls; + if (NULL == session->transaction_name) + return; /* all good */ + if (GNUNET_OK == + GNUNET_PQ_exec_statements (session->conn, + es)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "BUG: Preflight check committed transaction `%s'!\n", + session->transaction_name); + } + else + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "BUG: Preflight check failed to commit transaction `%s'!\n", + session->transaction_name); + } + session->transaction_name = NULL; +} + /** * Start a transaction. @@ -1029,6 +1068,8 @@ postgres_start (void *cls, GNUNET_PQ_EXECUTE_STATEMENT_END }; + postgres_preflight (cls, + session); (void) cls; if (GNUNET_OK != GNUNET_PQ_exec_statements (session->conn, diff --git a/src/exchangedb/plugin_exchangedb_postgres.c b/src/exchangedb/plugin_exchangedb_postgres.c index e4caec2d5..a657b405b 100644 --- a/src/exchangedb/plugin_exchangedb_postgres.c +++ b/src/exchangedb/plugin_exchangedb_postgres.c @@ -78,7 +78,7 @@ /** - * Handle for a database session (per-thread, for transactions). + * Handler for a database session (per-thread, for transactions). */ struct TALER_EXCHANGEDB_Session { @@ -1711,6 +1711,17 @@ postgres_get_session (void *cls) return session; } +/** + * Do a pre-flight check that we are not in an uncommitted transaction. + * If we are, try to commit the previous transaction and output a warning. + * Does not return anything, as we will continue regardless of the outcome. + * + * @param cls the `struct PostgresClosure` with the plugin-specific state + * @param session the database connection + */ +static void +postgres_preflight (void *cls, + struct TALER_EXCHANGEDB_Session *session); /** * Start a transaction. @@ -1731,6 +1742,9 @@ postgres_start (void *cls, GNUNET_PQ_EXECUTE_STATEMENT_END }; + postgres_preflight (cls, + session); + (void) cls; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting transaction on %p\n", @@ -1813,7 +1827,7 @@ postgres_preflight (void *cls, struct TALER_EXCHANGEDB_Session *session) { struct GNUNET_PQ_ExecuteStatement es[] = { - GNUNET_PQ_make_execute ("COMMIT"), + GNUNET_PQ_make_execute ("ROLLBACK"), GNUNET_PQ_EXECUTE_STATEMENT_END };