[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnunet] branch master updated: namestore: Add transaction handling to n
From: |
gnunet |
Subject: |
[gnunet] branch master updated: namestore: Add transaction handling to namestore API and plugins |
Date: |
Tue, 02 Jul 2024 10:49:49 +0200 |
This is an automated email from the git hooks/post-receive script.
martin-schanzenbach pushed a commit to branch master
in repository gnunet.
The following commit(s) were added to refs/heads/master by this push:
new 891d29d72 namestore: Add transaction handling to namestore API and
plugins
891d29d72 is described below
commit 891d29d727b09b5e5d0d8bcb170a770b0c30972f
Author: Martin Schanzenbach <schanzen@gnunet.org>
AuthorDate: Tue Jul 2 10:48:59 2024 +0200
namestore: Add transaction handling to namestore API and plugins
NEWS: Namestore records can not be inserted in a single transaction (if
plugin supports this)
---
src/include/gnunet_namestore_plugin.h | 33 +++++++++++
src/plugin/namestore/plugin_namestore_postgres.c | 70 ++++++++++++++++++++++++
src/plugin/namestore/plugin_namestore_sqlite.c | 69 +++++++++++++++++++++++
src/service/namestore/gnunet-service-namestore.c | 6 ++
src/service/namestore/namestore.h | 11 ++++
5 files changed, 189 insertions(+)
diff --git a/src/include/gnunet_namestore_plugin.h
b/src/include/gnunet_namestore_plugin.h
index 88e5e4be1..c354cb2cd 100644
--- a/src/include/gnunet_namestore_plugin.h
+++ b/src/include/gnunet_namestore_plugin.h
@@ -202,6 +202,39 @@ struct GNUNET_NAMESTORE_PluginFunctions
const struct GNUNET_CRYPTO_PrivateKey *zone,
const char *label);
+ /**
+ * Tell plugin that a set of procedures are coming that
+ * are ideally handled within a single TX (BEGIN/COMMIT).
+ * This may be implemented as a NOP, but can speed up
+ * store calls in some cases (e.g. SQL databases)
+ *
+ * @param cls closure (internal context for the plugin)
+ * @return #GNUNET_OK on success, else fails with #GNUNET_SYSERR
+ */
+ enum GNUNET_GenericReturnValue
+ (*begin_tx)(void *cls);
+
+ /**
+ * Tell plugin the we finished what we started with
+ * #begin_tx
+ *
+ * @param cls closure (internal context for the plugin)
+ * @return #GNUNET_OK on success, else fails with #GNUNET_SYSERR
+ */
+ enum GNUNET_GenericReturnValue
+ (*commit_tx)(void *cls);
+
+ /**
+ * Tell plugin to rollback what we started with
+ * #begin_tx
+ * This may be a NOP (and thus NOT roll anything back!)
+ *
+ * @param cls closure (internal context for the plugin)
+ * @return #GNUNET_OK on success, else fails with #GNUNET_SYSERR
+ */
+ enum GNUNET_GenericReturnValue
+ (*rollback_tx)(void *cls);
+
/**
* Setup the database.
*
diff --git a/src/plugin/namestore/plugin_namestore_postgres.c
b/src/plugin/namestore/plugin_namestore_postgres.c
index ccf84dfa6..e19ac410f 100644
--- a/src/plugin/namestore/plugin_namestore_postgres.c
+++ b/src/plugin/namestore/plugin_namestore_postgres.c
@@ -119,6 +119,17 @@ database_prepare (struct Plugin *plugin)
return GNUNET_OK;
{
struct GNUNET_PQ_PreparedStatement ps[] = {
+ GNUNET_PQ_make_prepare ("store_records_bulk",
+ "FOR i IN 1..cardinality($1) LOOP "
+ "INSERT INTO namestore.ns098records"
+ " (zone_private_key, pkey, rvalue, record_count,
record_data, label, editor_hint)"
+ " VALUES ($1, $2, $3, $4, $5, $6, '')"
+ " ON CONFLICT ON CONSTRAINT zl"
+ " DO UPDATE"
+ " SET
pkey=$2,rvalue=$3,record_count=$4,record_data=$5"
+ " WHERE ns098records.zone_private_key = $1"
+ " AND ns098records.label = $6"
+ " END LOOP"),
GNUNET_PQ_make_prepare ("store_records",
"INSERT INTO namestore.ns098records"
" (zone_private_key, pkey, rvalue, record_count,
record_data, label, editor_hint)"
@@ -709,6 +720,62 @@ namestore_postgres_zone_to_name (void *cls,
return GNUNET_OK;
}
+/**
+ *
+ * @param cls closure (internal context for the plugin)
+ * @return #GNUNET_OK on success, #GNUNET_NO for no results, else
#GNUNET_SYSERR
+ */
+static int
+namestore_postgres_begin_tx (void *cls)
+{
+
+ struct Plugin *plugin = cls;
+
+ struct GNUNET_PQ_ExecuteStatement ess[] = {
+ GNUNET_PQ_make_try_execute ("BEGIN"),
+ GNUNET_PQ_EXECUTE_STATEMENT_END
+ };
+ GNUNET_assert (GNUNET_OK == database_prepare (plugin));
+ return GNUNET_PQ_exec_statements(plugin->dbh, ess);
+}
+
+/**
+ *
+ * @param cls closure (internal context for the plugin)
+ * @return #GNUNET_OK on success, #GNUNET_NO for no results, else
#GNUNET_SYSERR
+ */
+static int
+namestore_postgres_commit_tx (void *cls)
+{
+
+ struct Plugin *plugin = cls;
+
+ struct GNUNET_PQ_ExecuteStatement ess[] = {
+ GNUNET_PQ_make_try_execute ("COMMIT"),
+ GNUNET_PQ_EXECUTE_STATEMENT_END
+ };
+ GNUNET_assert (GNUNET_OK == database_prepare (plugin));
+ return GNUNET_PQ_exec_statements(plugin->dbh, ess);
+}
+
+/**
+ *
+ * @param cls closure (internal context for the plugin)
+ * @return #GNUNET_OK on success, #GNUNET_NO for no results, else
#GNUNET_SYSERR
+ */
+static int
+namestore_postgres_rollback_tx (void *cls)
+{
+
+ struct Plugin *plugin = cls;
+
+ struct GNUNET_PQ_ExecuteStatement ess[] = {
+ GNUNET_PQ_make_try_execute ("ROLLBACK"),
+ GNUNET_PQ_EXECUTE_STATEMENT_END
+ };
+ GNUNET_assert (GNUNET_OK == database_prepare (plugin));
+ return GNUNET_PQ_exec_statements(plugin->dbh, ess);
+}
/**
* Shutdown database connection and associate data
@@ -755,6 +822,9 @@ libgnunet_plugin_namestore_postgres_init (void *cls)
api->lookup_records = &namestore_postgres_lookup_records;
api->edit_records = &namestore_postgres_edit_records;
api->clear_editor_hint = &namestore_postgres_clear_editor_hint;
+ api->begin_tx = &namestore_postgres_begin_tx;
+ api->commit_tx = &namestore_postgres_commit_tx;
+ api->rollback_tx = &namestore_postgres_rollback_tx;
LOG (GNUNET_ERROR_TYPE_INFO,
"Postgres namestore plugin running\n");
return api;
diff --git a/src/plugin/namestore/plugin_namestore_sqlite.c
b/src/plugin/namestore/plugin_namestore_sqlite.c
index 50c2f5728..6a416f332 100644
--- a/src/plugin/namestore/plugin_namestore_sqlite.c
+++ b/src/plugin/namestore/plugin_namestore_sqlite.c
@@ -903,6 +903,72 @@ namestore_sqlite_drop_tables (void *cls)
}
+static enum GNUNET_GenericReturnValue
+namestore_sqlite_begin_tx (void *cls)
+{
+ struct Plugin *plugin = cls;
+ struct GNUNET_SQ_ExecuteStatement es_drop[] = {
+ GNUNET_SQ_make_execute ("BEGIN"),
+ GNUNET_SQ_EXECUTE_STATEMENT_END
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_SQ_exec_statements (plugin->dbh,
+ es_drop))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to drop database with: `%s'\n",
+ sqlite3_errmsg (plugin->dbh));
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+}
+
+
+static enum GNUNET_GenericReturnValue
+namestore_sqlite_commit_tx (void *cls)
+{
+ struct Plugin *plugin = cls;
+ struct GNUNET_SQ_ExecuteStatement es_drop[] = {
+ GNUNET_SQ_make_execute ("COMMIT"),
+ GNUNET_SQ_EXECUTE_STATEMENT_END
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_SQ_exec_statements (plugin->dbh,
+ es_drop))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to drop database with: `%s'\n",
+ sqlite3_errmsg (plugin->dbh));
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+}
+
+
+static enum GNUNET_GenericReturnValue
+namestore_sqlite_rollback_tx (void *cls)
+{
+ struct Plugin *plugin = cls;
+ struct GNUNET_SQ_ExecuteStatement es_drop[] = {
+ GNUNET_SQ_make_execute ("ROLLBACK"),
+ GNUNET_SQ_EXECUTE_STATEMENT_END
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_SQ_exec_statements (plugin->dbh,
+ es_drop))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
+ "Failed to drop database with: `%s'\n",
+ sqlite3_errmsg (plugin->dbh));
+ return GNUNET_SYSERR;
+ }
+ return GNUNET_OK;
+}
+
+
/**
* Initialize the database connections and associated
* data structures (create tables and indices
@@ -999,6 +1065,9 @@ libgnunet_plugin_namestore_sqlite_init (void *cls)
api->drop_tables = &namestore_sqlite_drop_tables;
api->edit_records = &namestore_sqlite_edit_records;
api->clear_editor_hint = &namestore_sqlite_editor_hint_clear;
+ api->begin_tx = &namestore_sqlite_begin_tx;
+ api->commit_tx = &namestore_sqlite_commit_tx;
+ api->rollback_tx = &namestore_sqlite_rollback_tx;
LOG (GNUNET_ERROR_TYPE_DEBUG,
_ ("SQlite database running\n"));
return api;
diff --git a/src/service/namestore/gnunet-service-namestore.c
b/src/service/namestore/gnunet-service-namestore.c
index 4d8c41d05..0c5747f52 100644
--- a/src/service/namestore/gnunet-service-namestore.c
+++ b/src/service/namestore/gnunet-service-namestore.c
@@ -1946,6 +1946,8 @@ handle_record_store (void *cls, const struct
RecordStoreMessage *rp_msg)
rid = ntohl (rp_msg->gns_header.r_id);
rd_set_count = ntohs (rp_msg->rd_set_count);
buf = (const char *) rp_msg + rs_off;
+ if (GNUNET_YES == ntohs (rp_msg->single_tx))
+ GSN_database->begin_tx (GSN_database->cls);
for (int i = 0; i < rd_set_count; i++)
{
rs = (struct RecordSet *) buf;
@@ -1953,12 +1955,16 @@ handle_record_store (void *cls, const struct
RecordStoreMessage *rp_msg)
rs, &read);
if (GNUNET_EC_NONE != res)
{
+ if (GNUNET_YES == ntohs (rp_msg->single_tx))
+ GSN_database->rollback_tx (GSN_database->cls);
send_store_response (nc, res, rid);
GNUNET_SERVICE_client_continue (nc->client);
return;
}
buf += read;
}
+ if (GNUNET_YES == ntohs (rp_msg->single_tx))
+ GSN_database->commit_tx (GSN_database->cls);
sa = GNUNET_malloc (sizeof(struct StoreActivity) + rs_len);
GNUNET_CONTAINER_DLL_insert (sa_head, sa_tail, sa);
sa->nc = nc;
diff --git a/src/service/namestore/namestore.h
b/src/service/namestore/namestore.h
index 171eb6ee3..5866bc1d6 100644
--- a/src/service/namestore/namestore.h
+++ b/src/service/namestore/namestore.h
@@ -90,6 +90,17 @@ struct RecordStoreMessage
*/
struct GNUNET_NAMESTORE_Header gns_header;
+ /**
+ * Reserved
+ */
+ uint16_t reserved;
+
+ /**
+ * GNUNET_YES if all sets should be stored
+ * in a single transaction (e.g. BEGIN/COMMIT).
+ */
+ uint16_t single_tx GNUNET_PACKED;
+
/**
* Number of record sets
*/
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnunet] branch master updated: namestore: Add transaction handling to namestore API and plugins,
gnunet <=