[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnunet] 05/08: NAMESTORE: Add begin, commit and rollback API messages
From: |
gnunet |
Subject: |
[gnunet] 05/08: NAMESTORE: Add begin, commit and rollback API messages |
Date: |
Fri, 23 Sep 2022 06:01:09 +0200 |
This is an automated email from the git hooks/post-receive script.
martin-schanzenbach pushed a commit to branch master
in repository gnunet.
commit 52babbd648cd8b9ab7f49f26641f8ccf7d2fc4e8
Author: Martin Schanzenbach <schanzen@gnunet.org>
AuthorDate: Fri Sep 23 12:44:45 2022 +0900
NAMESTORE: Add begin, commit and rollback API messages
Namestore service can now handle begin commit and rollback.
A test for rollback exists and works for sqlite.
---
src/include/gnunet_namestore_service.h | 40 ++++++----
src/include/gnunet_protocols.h | 22 ++++++
src/namestore/Makefile.am | 13 +++-
src/namestore/gnunet-service-namestore.c | 55 +++++++++++++
src/namestore/namestore.h | 48 ++++++++++++
src/namestore/namestore_api.c | 128 +++++++++++++++++++++++++------
src/namestore/plugin_namestore_sqlite.c | 12 +--
7 files changed, 272 insertions(+), 46 deletions(-)
diff --git a/src/include/gnunet_namestore_service.h
b/src/include/gnunet_namestore_service.h
index 8b42945e1..68aeebef8 100644
--- a/src/include/gnunet_namestore_service.h
+++ b/src/include/gnunet_namestore_service.h
@@ -70,6 +70,16 @@ struct GNUNET_NAMESTORE_Handle;
*/
struct GNUNET_NAMESTORE_ZoneIterator;
+/**
+ * Transaction control types.
+ * They roughly correspond to DB transaction controls
+ */
+enum GNUNET_NAMESTORE_TxControl
+{
+ GNUNET_NAMESTORE_TX_BEGIN = 0,
+ GNUNET_NAMESTORE_TX_COMMIT = 1,
+ GNUNET_NAMESTORE_TX_ROLLBACK = 2,
+};
/**
* Connect to the namestore service.
@@ -404,44 +414,44 @@ GNUNET_NAMESTORE_zone_monitor_stop (struct
GNUNET_NAMESTORE_ZoneMonitor *zm);
* Begin a namestore transaction.
*
* @param h handle to the namestore
- * @param error_cb function to call on error (i.e. disconnect or unable to get
lock)
- * the handle is afterwards invalid
- * @param error_cb_cls closure for @a error_cb
+ * @param cont function to call on result
+ * @param cont_cls closure for @a cont
* @return handle to abort the request
*/
struct GNUNET_NAMESTORE_QueueEntry *
GNUNET_NAMESTORE_transaction_begin (struct GNUNET_NAMESTORE_Handle *h,
- GNUNET_SCHEDULER_TaskCallback error_cb,
- void *error_cb_cls);
+ GNUNET_NAMESTORE_ContinuationWithStatus
+ cont,
+ void *cont_cls);
/**
* Begin rollback all actions in a transaction.
* Reverts all actions performed since #GNUNET_NAMESTORE_transaction_begin
*
* @param h handle to the namestore
- * @param error_cb function to call on error (i.e. disconnect or unable to get
lock)
- * the handle is afterwards invalid
- * @param error_cb_cls closure for @a error_cb
+ * @param cont function to call on result
+ * @param cont_cls closure for @a cont
* @return handle to abort the request
*/
struct GNUNET_NAMESTORE_QueueEntry *
GNUNET_NAMESTORE_transaction_rollback (struct GNUNET_NAMESTORE_Handle *h,
- GNUNET_SCHEDULER_TaskCallback error_cb,
- void *error_cb_cls);
+ GNUNET_NAMESTORE_ContinuationWithStatus
+ cont,
+ void *cont_cls);
/**
* Commit a namestore transaction.
* Saves all actions performed since #GNUNET_NAMESTORE_transaction_begin
*
* @param h handle to the namestore
- * @param error_cb function to call on error (i.e. disconnect or unable to get
lock)
- * the handle is afterwards invalid
- * @param error_cb_cls closure for @a error_cb
+ * @param cont function to call on result
+ * @param cont_cls closure for @a cont
* @return handle to abort the request
*/
struct GNUNET_NAMESTORE_QueueEntry *
GNUNET_NAMESTORE_transaction_commit (struct GNUNET_NAMESTORE_Handle *h,
- GNUNET_SCHEDULER_TaskCallback error_cb,
- void *error_cb_cls);
+ GNUNET_NAMESTORE_ContinuationWithStatus
+ cont,
+ void *cont_cls);
#if 0 /* keep Emacsens' auto-indent happy */
{
diff --git a/src/include/gnunet_protocols.h b/src/include/gnunet_protocols.h
index dc66a0401..509c97fb2 100644
--- a/src/include/gnunet_protocols.h
+++ b/src/include/gnunet_protocols.h
@@ -3603,6 +3603,28 @@ extern "C" {
/*********************************************************************************/
+/*********************************************************************************/
+/********************************** NAMESTORE (cont.)
**************************/
+/*********************************************************************************/
+/* NAMESTORE: message types 1750-1800
+ */
+
+/**
+ * Message type for Begin, Commit or Rollback
+ */
+#define GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL 1750
+
+/**
+ * Return status message for control message
+ */
+#define GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL_RESULT 1751
+
+/**
+ * Open and lock records for editing message
+ */
+#define GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_EDIT 1752
+
+
/**
* Type used to match 'all' message types.
*/
diff --git a/src/namestore/Makefile.am b/src/namestore/Makefile.am
index 51708dd67..58e3c49f0 100644
--- a/src/namestore/Makefile.am
+++ b/src/namestore/Makefile.am
@@ -54,7 +54,8 @@ SQLITE_TESTS = test_plugin_namestore_sqlite \
test_namestore_api_zone_iteration_stop_sqlite \
test_namestore_api_monitoring_existing_sqlite \
test_namestore_api_zone_to_name_sqlite \
- perf_namestore_api_zone_iteration_sqlite
+ perf_namestore_api_zone_iteration_sqlite \
+ test_namestore_api_tx_rollback_sqlite
endif
if HAVE_POSTGRESQL
@@ -569,6 +570,16 @@ test_namestore_api_monitoring_existing_postgres_LDADD = \
$(top_builddir)/src/identity/libgnunetidentity.la \
$(top_builddir)/src/util/libgnunetutil.la
+test_namestore_api_tx_rollback_sqlite_SOURCES = \
+ test_namestore_api_tx_rollback.c
+test_namestore_api_tx_rollback_sqlite_LDADD = \
+ $(top_builddir)/src/testing/libgnunettesting.la \
+ $(top_builddir)/src/identity/libgnunetidentity.la \
+ libgnunetnamestore.la \
+ $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \
+ $(top_builddir)/src/util/libgnunetutil.la
+
+
test_namestore_api_zone_iteration_flat_SOURCES = \
test_namestore_api_zone_iteration.c
test_namestore_api_zone_iteration_flat_LDADD = \
diff --git a/src/namestore/gnunet-service-namestore.c
b/src/namestore/gnunet-service-namestore.c
index a173e8927..1f621c5f0 100644
--- a/src/namestore/gnunet-service-namestore.c
+++ b/src/namestore/gnunet-service-namestore.c
@@ -1728,6 +1728,57 @@ handle_record_store (void *cls, const struct
RecordStoreMessage *rp_msg)
}
}
+/**
+ * Handles a #GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL message
+ *
+ * @param cls client sending the message
+ * @param tx_msg message of type `struct TxControlMessage`
+ */
+static void
+handle_tx_control (void *cls, const struct TxControlMessage *tx_msg)
+{
+ struct NamestoreClient *nc = cls;
+ struct TxControlResultMessage *txr_msg;
+ struct GNUNET_MQ_Envelope *env;
+ enum GNUNET_GenericReturnValue ret;
+ char *emsg;
+ char *err_tmp;
+ size_t err_len;
+
+ switch (ntohs (tx_msg->control))
+ {
+ case GNUNET_NAMESTORE_TX_BEGIN:
+ ret = nc->GSN_database->transaction_begin (nc->GSN_database->cls,
+ &emsg);
+ break;
+ case GNUNET_NAMESTORE_TX_COMMIT:
+ ret = nc->GSN_database->transaction_commit (nc->GSN_database->cls,
+ &emsg);
+ break;
+ case GNUNET_NAMESTORE_TX_ROLLBACK:
+ ret = nc->GSN_database->transaction_rollback (nc->GSN_database->cls,
+ &emsg);
+ break;
+ default:
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Unknown control type %u\n", ntohs (tx_msg->control));
+ GNUNET_break (0);
+ }
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "TX status is %u\n", ret);
+ err_len = (GNUNET_YES == ret) ? 0 : strlen (emsg) + 1;
+ env =
+ GNUNET_MQ_msg_extra (txr_msg,
+ err_len,
+ GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL_RESULT);
+ txr_msg->gns_header.header.size = htons (sizeof (struct
TxControlResultMessage) + err_len);
+ txr_msg->gns_header.r_id = tx_msg->gns_header.r_id;
+ txr_msg->success = htons (ret);
+ err_tmp = (char *) &txr_msg[1];
+ GNUNET_memcpy (err_tmp, emsg, err_len);
+ GNUNET_MQ_send (nc->mq, env);
+ GNUNET_SERVICE_client_continue (nc->client);
+}
/**
* Context for record remove operations passed from #handle_zone_to_name to
@@ -2371,6 +2422,10 @@ GNUNET_SERVICE_MAIN (
&client_connect_cb,
&client_disconnect_cb,
NULL,
+ GNUNET_MQ_hd_fixed_size (tx_control,
+ GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL,
+ struct TxControlMessage,
+ NULL),
GNUNET_MQ_hd_var_size (record_store,
GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_STORE,
struct RecordStoreMessage,
diff --git a/src/namestore/namestore.h b/src/namestore/namestore.h
index 583ec1e68..06feee13a 100644
--- a/src/namestore/namestore.h
+++ b/src/namestore/namestore.h
@@ -305,6 +305,54 @@ struct RecordResultMessage
*/
};
+/**
+ * Send a transaction control message.
+ */
+struct TxControlMessage
+{
+ /**
+ * Type will be #GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL
+ */
+ struct GNUNET_NAMESTORE_Header gns_header;
+
+ /**
+ * The type of control message to send
+ */
+ uint16_t control GNUNET_PACKED;
+
+ /**
+ * always zero (for alignment)
+ */
+ uint16_t reserved GNUNET_PACKED;
+
+};
+
+/**
+ * Result of a transaction control message.
+ */
+struct TxControlResultMessage
+{
+ /**
+ * Type will be #GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL_RESULT
+ */
+ struct GNUNET_NAMESTORE_Header gns_header;
+
+ /**
+ * The type of control message to send
+ */
+ uint16_t control GNUNET_PACKED;
+
+ /**
+ * Of type GNUNET_GenericReturnValue
+ */
+ uint16_t success GNUNET_PACKED;
+
+ /* followed by:
+ * an error message if status != ntohs(GNUNET_OK)
+ */
+};
+
+
/**
* Start monitoring a zone.
diff --git a/src/namestore/namestore_api.c b/src/namestore/namestore_api.c
index 67541b45a..26e1477f4 100644
--- a/src/namestore/namestore_api.c
+++ b/src/namestore/namestore_api.c
@@ -674,6 +674,60 @@ handle_record_result_end (void *cls, const struct
GNUNET_NAMESTORE_Header *msg)
free_ze (ze);
}
+/**
+ * Handle an incoming message of type
+ * #GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL_RESULT.
+ *
+ * @param qe the respective entry in the message queue
+ * @param msg the message we received
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR if message malformed
+ */
+static int
+check_tx_control_result (void *cls,
+ const struct TxControlResultMessage *msg)
+{
+ const char *err_tmp;
+ size_t err_len;
+
+ (void) cls;
+ err_len = ntohs (msg->gns_header.header.size)
+ - sizeof (struct TxControlResultMessage);
+ if ((GNUNET_YES == ntohs (msg->success)) && (err_len > 0))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ err_tmp = (const char *) &msg[1];
+ if ((err_len > 0) && ('\0' != err_tmp[err_len - 1]))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+}
+
+static void
+handle_tx_control_result (void *cls,
+ const struct TxControlResultMessage *msg)
+{
+ struct GNUNET_NAMESTORE_Handle *h = cls;
+ struct GNUNET_NAMESTORE_QueueEntry *qe;
+ int res;
+ const char *emsg;
+
+ qe = find_qe (h, ntohl (msg->gns_header.r_id));
+ emsg = (const char *) &msg[1];
+ res = ntohs (msg->success);
+ LOG (GNUNET_ERROR_TYPE_DEBUG,
+ "Received TX_CONTROL_RESULT with result %d\n",
+ res);
+ if (NULL == qe)
+ return;
+ if (NULL != qe->cont)
+ qe->cont (qe->cont_cls, res,
+ (GNUNET_YES == res) ? NULL : emsg);
+ free_qe (qe);
+}
/**
* Handle an incoming message of type
@@ -839,6 +893,10 @@ reconnect (struct GNUNET_NAMESTORE_Handle *h)
GNUNET_MESSAGE_TYPE_NAMESTORE_RECORD_LOOKUP_RESPONSE,
struct LabelLookupResponseMessage,
h),
+ GNUNET_MQ_hd_var_size (tx_control_result,
+ GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL_RESULT,
+ struct TxControlResultMessage,
+ h),
GNUNET_MQ_handler_end () };
struct GNUNET_NAMESTORE_ZoneIterator *it;
struct GNUNET_NAMESTORE_QueueEntry *qe;
@@ -1344,43 +1402,65 @@ GNUNET_NAMESTORE_cancel (struct
GNUNET_NAMESTORE_QueueEntry *qe)
* New API draft. Experimental
*/
-struct GNUNET_NAMESTORE_QueueEntry *
-GNUNET_NAMESTORE_transaction_begin (struct GNUNET_NAMESTORE_Handle *h,
- GNUNET_SCHEDULER_TaskCallback error_cb,
- void *error_cb_cls)
+static struct GNUNET_NAMESTORE_QueueEntry *
+send_transaction_control_msg (struct GNUNET_NAMESTORE_Handle *h,
+ GNUNET_NAMESTORE_ContinuationWithStatus cont,
+ void *cont_cls,
+ enum GNUNET_NAMESTORE_TxControl ctrl)
{
+ struct GNUNET_NAMESTORE_QueueEntry *qe;
+ struct GNUNET_MQ_Envelope *env;
+ struct TxControlMessage *msg;
+ uint32_t rid;
+
+ rid = get_op_id (h);
+ qe = GNUNET_new (struct GNUNET_NAMESTORE_QueueEntry);
+ qe->h = h;
+ qe->cont = cont;
+ qe->cont_cls = cont_cls;
+ qe->op_id = rid;
+ GNUNET_CONTAINER_DLL_insert_tail (h->op_head, h->op_tail, qe);
+
+ env = GNUNET_MQ_msg (msg, GNUNET_MESSAGE_TYPE_NAMESTORE_TX_CONTROL);
+ msg->gns_header.r_id = htonl (rid);
+ msg->control = htons (ctrl);
+ if (NULL == h->mq)
+ qe->env = env;
+ else
+ GNUNET_MQ_send (h->mq, env);
+ return qe;
GNUNET_break (0);
return NULL;
}
+struct GNUNET_NAMESTORE_QueueEntry *
+GNUNET_NAMESTORE_transaction_begin (struct GNUNET_NAMESTORE_Handle *h,
+ GNUNET_NAMESTORE_ContinuationWithStatus
cont,
+ void *cont_cls)
+{
+ return send_transaction_control_msg (h, cont, cont_cls,
+ GNUNET_NAMESTORE_TX_BEGIN);
+}
struct GNUNET_NAMESTORE_QueueEntry *
-GNUNET_NAMESTORE_transaction_rollback (struct GNUNET_NAMESTORE_Handle *h,
- GNUNET_SCHEDULER_TaskCallback error_cb,
- void *error_cb_cls)
+GNUNET_NAMESTORE_transaction_commit (struct GNUNET_NAMESTORE_Handle *h,
+ GNUNET_NAMESTORE_ContinuationWithStatus
+ cont,
+ void *cont_cls)
{
- GNUNET_break (0);
- return NULL;
+ return send_transaction_control_msg (h, cont, cont_cls,
+ GNUNET_NAMESTORE_TX_COMMIT);
}
-/**
- * Commit a namestore transaction.
- * Saves all actions performed since #GNUNET_NAMESTORE_transaction_begin
- *
- * @param h handle to the namestore
- * @param error_cb function to call on error (i.e. disconnect or unable to get
lock)
- * the handle is afterwards invalid
- * @param error_cb_cls closure for @a error_cb
- * @return handle to abort the request
- */
struct GNUNET_NAMESTORE_QueueEntry *
-GNUNET_NAMESTORE_transaction_commit (struct GNUNET_NAMESTORE_Handle *h,
- GNUNET_SCHEDULER_TaskCallback error_cb,
- void *error_cb_cls)
+GNUNET_NAMESTORE_transaction_rollback (struct GNUNET_NAMESTORE_Handle *h,
+ GNUNET_NAMESTORE_ContinuationWithStatus
+ cont,
+ void *cont_cls)
{
- GNUNET_break (0);
- return NULL;
+ return send_transaction_control_msg (h, cont, cont_cls,
+ GNUNET_NAMESTORE_TX_ROLLBACK);
}
diff --git a/src/namestore/plugin_namestore_sqlite.c
b/src/namestore/plugin_namestore_sqlite.c
index fd81780fb..d434abd94 100644
--- a/src/namestore/plugin_namestore_sqlite.c
+++ b/src/namestore/plugin_namestore_sqlite.c
@@ -748,7 +748,7 @@ namestore_sqlite_zone_to_name (void *cls,
*
* @param cls closure (internal context for the plugin)
* @param emsg error message set of return code is #GNUNET_SYSERR
- * @return #GNUNET_OK on success, #GNUNET_SYSERR if transaction cannot be
started.
+ * @return #GNUNET_YES on success, #GNUNET_SYSERR if transaction cannot be
started.
*/
static enum GNUNET_GenericReturnValue
namestore_sqlite_transaction_begin (void *cls,
@@ -756,7 +756,7 @@ namestore_sqlite_transaction_begin (void *cls,
{
struct Plugin *plugin = cls;
return (SQLITE_BUSY == sqlite3_exec (plugin->dbh, "BEGIN TRANSACTION;", NULL,
- NULL, emsg)) ? GNUNET_SYSERR :
GNUNET_OK;
+ NULL, emsg)) ? GNUNET_SYSERR :
GNUNET_YES;
}
/**
@@ -765,7 +765,7 @@ namestore_sqlite_transaction_begin (void *cls,
*
* @param cls closure (internal context for the plugin)
* @param emsg error message set of return code is #GNUNET_SYSERR
- * @return #GNUNET_OK on success, #GNUNET_SYSERR if transaction cannot be
started.
+ * @return #GNUNET_YES on success, #GNUNET_SYSERR if transaction cannot be
started.
*/
static enum GNUNET_GenericReturnValue
namestore_sqlite_transaction_rollback (void *cls,
@@ -773,7 +773,7 @@ namestore_sqlite_transaction_rollback (void *cls,
{
struct Plugin *plugin = cls;
return (SQLITE_BUSY == sqlite3_exec (plugin->dbh, "ROLLBACK;", NULL,
- NULL, emsg)) ? GNUNET_SYSERR :
GNUNET_OK;
+ NULL, emsg)) ? GNUNET_SYSERR :
GNUNET_YES;
}
/**
@@ -782,7 +782,7 @@ namestore_sqlite_transaction_rollback (void *cls,
*
* @param cls closure (internal context for the plugin)
* @param emsg error message set of return code is #GNUNET_SYSERR
- * @return #GNUNET_OK on success, #GNUNET_SYSERR if transaction cannot be
started.
+ * @return #GNUNET_YES on success, #GNUNET_SYSERR if transaction cannot be
started.
*/
static enum GNUNET_GenericReturnValue
namestore_sqlite_transaction_commit (void *cls,
@@ -790,7 +790,7 @@ namestore_sqlite_transaction_commit (void *cls,
{
struct Plugin *plugin = cls;
return (SQLITE_BUSY == sqlite3_exec (plugin->dbh, "END TRANSACTION;", NULL,
- NULL, emsg)) ? GNUNET_SYSERR :
GNUNET_OK;
+ NULL, emsg)) ? GNUNET_SYSERR :
GNUNET_YES;
}
/**
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [gnunet] branch master updated (1672c85ad -> 8ecf052b2), gnunet, 2022/09/23
- [gnunet] 03/08: NAMESTORE: Fix existing monitoring test race condition, gnunet, 2022/09/23
- [gnunet] 01/08: NAMESTORE: Start transactional API, gnunet, 2022/09/23
- [gnunet] 04/08: NAMESTORE: Use a per client database connection, gnunet, 2022/09/23
- [gnunet] 06/08: NAMESTORE: Remove head based database, gnunet, 2022/09/23
- [gnunet] 07/08: NAMESTORE: Add tx API for postgres, gnunet, 2022/09/23
- [gnunet] 02/08: NAMESTORE: Remove unneeded functions and renames., gnunet, 2022/09/23
- [gnunet] 05/08: NAMESTORE: Add begin, commit and rollback API messages,
gnunet <=
- [gnunet] 08/08: Merge branch 'dev/schanzen/namestore_transactions', gnunet, 2022/09/23