From 8c33ea5a6ba48f26edad61ce9198e1a793e9e1cc Mon Sep 17 00:00:00 2001 From: akwizgran Date: Fri, 24 Dec 2021 12:00:15 +0000 Subject: [PATCH] Add javadocs for database. --- .../bramble/api/db/DatabaseComponent.java | 7 ++ .../bramble/api/db/DatabaseExecutor.java | 4 ++ .../bramble/api/db/Transaction.java | 6 ++ .../bramble/api/db/TransactionManager.java | 68 +++++++++++++++---- 4 files changed, 73 insertions(+), 12 deletions(-) diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/db/DatabaseComponent.java b/bramble-api/src/main/java/org/briarproject/bramble/api/db/DatabaseComponent.java index ea507351b..975c4ba15 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/db/DatabaseComponent.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/db/DatabaseComponent.java @@ -33,11 +33,18 @@ import java.util.List; import java.util.Map; import javax.annotation.Nullable; +import javax.annotation.concurrent.ThreadSafe; /** * Encapsulates the database implementation and exposes high-level operations * to other components. + *

+ * With the exception of the {@link #open(SecretKey, MigrationListener)} and + * {@link #close()} methods, which must not be called concurrently, the + * database can be accessed from any thread. See {@link TransactionManager} + * for locking behaviour. */ +@ThreadSafe @NotNullByDefault public interface DatabaseComponent extends TransactionManager { diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/db/DatabaseExecutor.java b/bramble-api/src/main/java/org/briarproject/bramble/api/db/DatabaseExecutor.java index 256be229a..b1fae6e05 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/db/DatabaseExecutor.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/db/DatabaseExecutor.java @@ -18,6 +18,10 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; * submitted, tasks are not run concurrently, and submitting a task will never * block. Tasks must not run indefinitely. Tasks submitted during shutdown are * discarded. + *

+ * It is not mandatory to use this executor for database tasks. The database + * can be accessed from any thread, but this executor's guarantee that tasks + * are run in the order they're submitted may be useful in some cases. */ @Qualifier @Target({FIELD, METHOD, PARAMETER}) diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/db/Transaction.java b/bramble-api/src/main/java/org/briarproject/bramble/api/db/Transaction.java index e54da0064..cdb6e3980 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/db/Transaction.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/db/Transaction.java @@ -45,6 +45,9 @@ public class Transaction { /** * Attaches an event to be broadcast when the transaction has been * committed. The event will be broadcast on the {@link EventExecutor}. + * Events and {@link #attach(Runnable) tasks} are submitted to the + * {@link EventExecutor} in the order they were attached to the + * transaction. */ public void attach(Event e) { if (actions == null) actions = new ArrayList<>(); @@ -54,6 +57,9 @@ public class Transaction { /** * Attaches a task to be executed when the transaction has been * committed. The task will be run on the {@link EventExecutor}. + * {@link #attach(Event) Events} and tasks are submitted to the + * {@link EventExecutor} in the order they were attached to the + * transaction. */ public void attach(Runnable r) { if (actions == null) actions = new ArrayList<>(); diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/db/TransactionManager.java b/bramble-api/src/main/java/org/briarproject/bramble/api/db/TransactionManager.java index 6850c5b99..2ed25caf3 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/db/TransactionManager.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/db/TransactionManager.java @@ -1,51 +1,95 @@ package org.briarproject.bramble.api.db; +import org.briarproject.bramble.api.event.EventExecutor; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import javax.annotation.Nullable; +import javax.annotation.concurrent.ThreadSafe; +/** + * An interface for managing database transactions. + *

+ * Read-only transactions may access the database concurrently. Read-write + * transactions access the database exclusively, so starting a read-only or + * read-write transaction will block until there are no read-write + * transactions in progress. + *

+ * Failing to {@link #endTransaction(Transaction) end} a transaction will + * prevent other callers from accessing the database, so it is recommended to + * use the {@link #transaction(boolean, DbRunnable)}, + * {@link #transactionWithResult(boolean, DbCallable)} and + * {@link #transactionWithNullableResult(boolean, NullableDbCallable)} methods + * where possible, which handle committing or aborting the transaction on the + * caller's behalf. + *

+ * Transactions are not reentrant, i.e. it is not permitted to start a + * transaction on a thread that already has a transaction in progress. + */ +@ThreadSafe @NotNullByDefault public interface TransactionManager { /** - * Starts a new transaction and returns an object representing it. - *

- * This method acquires locks, so it must not be called while holding a - * lock. + * Starts a new transaction and returns an object representing it. This + * method acquires the database lock, which is held until + * {@link #endTransaction(Transaction)} is called. * - * @param readOnly true if the transaction will only be used for reading. + * @param readOnly True if the transaction will only be used for reading, + * in which case the database lock can be shared with other read-only + * transactions. */ Transaction startTransaction(boolean readOnly) throws DbException; /** * Commits a transaction to the database. + * {@link #endTransaction(Transaction)} must be called to release the + * database lock. */ void commitTransaction(Transaction txn) throws DbException; /** - * Ends a transaction. If the transaction has not been committed, - * it will be aborted. If the transaction has been committed, - * any events attached to the transaction are broadcast. - * The database lock will be released in either case. + * Ends a transaction. If the transaction has not been committed by + * calling {@link #commitTransaction(Transaction)}, it is aborted and the + * database lock is released. + *

+ * If the transaction has been committed, any + * {@link Transaction#attach events} attached to the transaction are + * broadcast and any {@link Transaction#attach(Runnable) tasks} attached + * to the transaction are submitted to the {@link EventExecutor}. The + * database lock is then released. */ void endTransaction(Transaction txn); /** - * Runs the given task within a transaction. + * Runs the given task within a transaction. The database lock is held + * while running the task. + * + * @param readOnly True if the transaction will only be used for reading, + * in which case the database lock can be shared with other read-only + * transactions. */ void transaction(boolean readOnly, DbRunnable task) throws DbException, E; /** * Runs the given task within a transaction and returns the result of the - * task. + * task. The database lock is held while running the task. + * + * @param readOnly True if the transaction will only be used for reading, + * in which case the database lock can be shared with other read-only + * transactions. */ R transactionWithResult(boolean readOnly, DbCallable task) throws DbException, E; /** * Runs the given task within a transaction and returns the result of the - * task, which may be null. + * task, which may be null. The database lock is held while running the + * task. + * + * @param readOnly True if the transaction will only be used for reading, + * in which case the database lock can be shared with other read-only + * transactions. */ @Nullable R transactionWithNullableResult(boolean readOnly,