From 1019930229be1c1c750d8dae1e2d606cb50e09ce Mon Sep 17 00:00:00 2001 From: Daniel Hornung <d.hornung@indiscale.com> Date: Wed, 10 Feb 2021 09:50:26 +0100 Subject: [PATCH] DOC STY: Some documentation, typos, ... --- CHANGELOG.md | 2 + .../java/org/caosdb/server/CaosDBServer.java | 6 +- .../server/database/BackendTransaction.java | 2 +- .../database/DatabaseAccessManager.java | 142 +++++++++++------- .../entity/container/WritableContainer.java | 2 + .../server/jobs/core/InsertFilesInDir.java | 2 + .../server/transaction/WriteTransaction.java | 19 ++- .../org/caosdb/server/utils/EntityStatus.java | 33 ++-- 8 files changed, 132 insertions(+), 76 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c862661..4bbc6cfb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Removed +* Text user interface (CaosDBTerminal). + ### Fixed * Bug: When the user password is updated the user is deactivated. diff --git a/src/main/java/org/caosdb/server/CaosDBServer.java b/src/main/java/org/caosdb/server/CaosDBServer.java index 82d79177..4a69f24d 100644 --- a/src/main/java/org/caosdb/server/CaosDBServer.java +++ b/src/main/java/org/caosdb/server/CaosDBServer.java @@ -159,8 +159,10 @@ public class CaosDBServer extends Application { /** * Parse the command line arguments. * - * <p>- "nobackend": flag to run caosdb without any backend (for testing purposes) - "insecure": - * flag to start only a http server (no https server) + * <ul> + * <li>"nobackend": flag to run caosdb without any backend (for testing purposes) + * <li>"insecure": flag to start only a http server (no https server) + * </ul> * * <p>Both flags are only available in the debug mode which is controlled by the `caosdb.debug` * JVM Property. diff --git a/src/main/java/org/caosdb/server/database/BackendTransaction.java b/src/main/java/org/caosdb/server/database/BackendTransaction.java index edf9b16f..61aebf42 100644 --- a/src/main/java/org/caosdb/server/database/BackendTransaction.java +++ b/src/main/java/org/caosdb/server/database/BackendTransaction.java @@ -298,7 +298,7 @@ public abstract class BackendTransaction implements Undoable { } } - /** Returns the type of transaction of an entity, e.g. "Retrieve" for a {@link RetrieveEntity}. */ + /** Return the type of transaction of an entity, e.g. "Retrieve" for a {@link RetrieveEntity}. */ public String getTransactionType(EntityInterface e) { return e.getClass().getSimpleName().replace("Entity", ""); } diff --git a/src/main/java/org/caosdb/server/database/DatabaseAccessManager.java b/src/main/java/org/caosdb/server/database/DatabaseAccessManager.java index de468545..72710daf 100644 --- a/src/main/java/org/caosdb/server/database/DatabaseAccessManager.java +++ b/src/main/java/org/caosdb/server/database/DatabaseAccessManager.java @@ -4,6 +4,9 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2021 Indiscale GmbH <info@indiscale.com> + * Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com> + * Copyright (C) 2021 Daniel Hornung <d.hornung@indiscale.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -39,10 +42,10 @@ import org.caosdb.server.utils.Releasable; /** * Acquire and release read access. DatabaseMonitor uses this class for managing access to entities * during processing updates, inserts, deletions and retrievals. Read access will be granted - * immediately for every thread that requests it, unless one or more threads requested for blocking - * the read access (usually due to requesting for write access). If this happens, all threads that - * already have read access will proceed and release their read access as usual but no NEW permits - * will be granted. + * immediately for every thread that requests it, unless a thread requests that read access be + * blocked (usually by requesting write access). If this happens, all threads that already have read + * access will proceed and release their read access as usual but no NEW read permits will be + * granted. * * <p>This is a blockable {@link Semaphore}. Any number of threads may acquire a permit unless it is * blocked. The blocking thread (requesting a {@link WriteAccessLock}) waits until all threads have @@ -53,8 +56,10 @@ import org.caosdb.server.utils.Releasable; class ReadAccessSemaphore extends Semaphore implements Releasable { private static final long serialVersionUID = 4384921156838881337L; - private int acquired = 0; // how many thread have read access - Semaphore block = new Semaphore(1, true); + private int acquired = 0; // how many threads have read access + Semaphore writersBlock = + new Semaphore(1, true); // This semaphore is blocked as long as there are any + // unreleased read permits. public ReadAccessSemaphore() { // this is a fair semaphore with no initial permit. @@ -62,55 +67,65 @@ class ReadAccessSemaphore extends Semaphore implements Releasable { } /** - * Acquires a read access permit if and only if it has not been blocked via block(). If the - * ReadAccess is currently blocked, the thread wait until the unblock() method is invoked by any - * thread. + * Acquire a read access permit if and only if it has not been blocked via block(). If read access + * is currently blocked, the thread waits until the unblock() method is invoked by any thread. */ @Override public void acquire() throws InterruptedException { - super.acquire(); + super.acquire(); // Protect the next few lines if (this.acquired == 0) { - this.block.acquire(); + this.writersBlock.acquire(); } this.acquired++; - // notifyObservers(null); super.release(); } - /** Releases a read access permit. */ + /** + * Release a read access permit. + * + * <p>If this is the last remaining acquired permit, also release the general writersBlock. + */ @Override public void release() { this.acquired--; - if (this.acquired <= 0) { + if (this.acquired <= 0) { // Last permit: release this.acquired = 0; - if (this.block.availablePermits() <= 0) { - this.block.release(); + if (this.writersBlock.availablePermits() <= 0) { + this.writersBlock.release(); } } } /** - * Acquires the permit of a block of read access if no thread currently has a read access and no - * thread currently has a block. I.e. it blocks the further permission of read access for any - * thread. Every thread that has a read access yet can proceed. The current thread waits until any - * thread has released its read access. If another thread has invoked this method yet the current - * thread waits until the unblock() method is called. + * Acquire the permit to block further read access, if no thread currently has acquired read + * access and no thread currently has a block. + * + * <p>Consequences of calling this method are: + * + * <ul> + * <li>Further read access permits are blocked for any thread. + * <li>Every thread that has a read access already can proceed. The current thread waits until + * all threads have released their read access. + * </ul> + * + * <p>If another thread has invoked this method before, the current thread waits until the + * unblock() method is called. * * @throws InterruptedException */ public void block() throws InterruptedException { super.reducePermits(1); - this.block.acquire(); + this.writersBlock.acquire(); } /** * Unblock read access. * - * @throws InterruptedException + * <p>This method releases the writersBlock introduced by calling the block() method. */ public void unblock() { - if (this.block.availablePermits() <= 0) { - this.block.release(); + if (this.writersBlock.availablePermits() <= 0) { + this.writersBlock.release(); } super.release(); } @@ -121,29 +136,47 @@ class ReadAccessSemaphore extends Semaphore implements Releasable { } /** - * Acquire and release write access. DatabaseMonitor uses this class for managing access to entities - * during processing updates, inserts, deletions and retrievals. Write access will be granted to one - * and only one thread if no other thread yet holds read or write access permits. The write access - * has to be allocated before requesting it to be permitted. See below. + * Acquire and release write access. DatabaseAccessManager uses this class for managing access to + * entities while processing updates, inserts, deletions and retrievals. Write access will be + * granted to one and only one thread if no other thread already holds read or write access permits. + * The write access seat has to be reserved before acquiring the lock. + * + * <p>The flow is as follows: + * + * <p> + * + * <pre> + * No new read + * access possible, + * Read access Read access wait for running read + * possible possible threads to fininish + * + * +------+ +----------+ +----------+ + * +--> | no | ----> | reserved | ----> | acquired | --+ + * | | Lock | +----------+ +----------+ | + * | +------+ \ / | + * | (1 seat together) | + * +-----------------------------------------------------+ + * release() + * </pre> * * @author Timm Fitschen */ class WriteAccessLock extends ReentrantLock implements Releasable { - private static final long serialVersionUID = -262226321839837533L; - private ReadAccessSemaphore wa = null; + private static final long serialVersionUID = 833147084787201103L; + private ReadAccessSemaphore readSem = null; private Thread reservedBy = null; - // private Thread acquiredBy = null; - public WriteAccessLock(final ReadAccessSemaphore wa) { + public WriteAccessLock(final ReadAccessSemaphore readSem) { super(); - this.wa = wa; + this.readSem = readSem; } /** - * Reserve the write access. While a write access is reserved but not yet acquired any read access - * may still be granted. When a write access is yet granted or another reservation is still - * active, the thread waits until the write access has been released. + * Reserve the seat for the next write access. While a write access is reserved but not yet + * acquired, all read access may still be granted. When a write access has been already granted or + * another reservation is active, the thread waits until the write access has been released. * * @throws InterruptedException */ @@ -152,18 +185,22 @@ class WriteAccessLock extends ReentrantLock implements Releasable { this.reservedBy = Thread.currentThread(); } + /** + * Lock the write access seat. This method returns once all current read permits have been + * released. + */ @Override public void lockInterruptibly() throws InterruptedException { if (!super.isHeldByCurrentThread()) { super.lock(); } - this.wa.block(); + this.readSem.block(); // Wait until all current read permits have been released. } @Override public void unlock() { if (super.isHeldByCurrentThread()) { - this.wa.unblock(); + this.readSem.unblock(); this.reservedBy = null; super.unlock(); } @@ -207,14 +244,14 @@ public class DatabaseAccessManager { } /** - * Acquire read access. This method returns the Access object as soon as there is no write access - * acquired. + * Acquire read access. This method returns the Access object as soon as there are no active write + * permits. * * <p>The returned Access object can be used to read in the data base back-end. * - * <p>Read access can be acquired parallel to other threads having read access or while other - * thread only reserved write access. As soon as any thread has requested to acquire write access, - * all other threads have to wait. + * <p>Read access can be acquired parallel to other threads having read access or while another + * thread has <em>reserved</em> write access. As soon as any thread has requested to + * <em>acquire</em> write access, all other threads have to wait. * * @param t the {@link TransactionInterface} which requests the read access * @return {@link Access} object which holds and abstract away all connection details. @@ -226,16 +263,13 @@ public class DatabaseAccessManager { } /** - * Reserve write access. This method returns the Access object as soon as there is no other thread - * which reserved or acquired the write access. Otherwise this thread waits in the queue until it - * can reserve the write access. + * Reserve write access. This method returns the Access object as soon as there is no other + * reserved or acquired write access. * * <p>The returned Access object can be used to read in the data base back-end. * - * <p>While a write access is reserved but not yet acquired any read access may still be granted. - * When a write access is yet granted or another reservation is still active, no read or write - * accesses can be granted and all other thread have to waits until this write access has been - * released. + * <p>The reservation has no effect on granting of read access permits, but only one thread may at + * any time reserve or acquire write access. * * @param wt - the {@link WriteTransactionInterface} which request the reservation of the write * access. @@ -248,9 +282,9 @@ public class DatabaseAccessManager { } /** - * Acquire write access. This method returns the Access object ass soon as all already acquired - * read accesses have been released. When the write access is acquired, no other access can be - * acquired (read or write). + * Acquire write access. This method returns the Access object as soon as all already acquired + * read access permits have been released. When the write access is acquired, no other access can + * be acquired (read or write). * * <p>The returned Access object can be used to read and write in the data base back-end. * diff --git a/src/main/java/org/caosdb/server/entity/container/WritableContainer.java b/src/main/java/org/caosdb/server/entity/container/WritableContainer.java index 3b440569..5fdb8c39 100644 --- a/src/main/java/org/caosdb/server/entity/container/WritableContainer.java +++ b/src/main/java/org/caosdb/server/entity/container/WritableContainer.java @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2021 Indiscale GmbH <info@indiscale.com> + * Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as diff --git a/src/main/java/org/caosdb/server/jobs/core/InsertFilesInDir.java b/src/main/java/org/caosdb/server/jobs/core/InsertFilesInDir.java index 4aedc0cb..52d46a37 100644 --- a/src/main/java/org/caosdb/server/jobs/core/InsertFilesInDir.java +++ b/src/main/java/org/caosdb/server/jobs/core/InsertFilesInDir.java @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2021 Indiscale GmbH <info@indiscale.com> + * Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as diff --git a/src/main/java/org/caosdb/server/transaction/WriteTransaction.java b/src/main/java/org/caosdb/server/transaction/WriteTransaction.java index c54eb6f7..0f1fd21b 100644 --- a/src/main/java/org/caosdb/server/transaction/WriteTransaction.java +++ b/src/main/java/org/caosdb/server/transaction/WriteTransaction.java @@ -4,8 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen - * Copyright (C) 2020 IndiScale GmbH <info@indiscale.com> - * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com> + * Copyright (C) 2021 IndiScale GmbH <info@indiscale.com> + * Copyright (C) 2021 Timm Fitschen <t.fitschen@indiscale.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -60,7 +60,7 @@ import org.caosdb.server.utils.ServerMessages; * This class is responsible for inserting, updating and deleting entities which are held in the * {@link TransactionContainer}. * - * <p>This class initializes and run the {@link Schedule} of {@link Job}s, calls the {@link + * <p>This class initializes and runs the {@link Schedule} of {@link Job}s, calls the {@link * BackendTransaction}s for each entity, and handles exceptions, roll-back (if necessary) and clean * up afterwards. * @@ -150,17 +150,15 @@ public class WriteTransaction extends Transaction<WritableContainer> } } - // allocate strong (write) access. Only one thread can do this - // at a time. But weak access can still be acquired by other - // thread until the allocated strong access is actually - // acquired. + // Reserve write access. Only one thread can do this at a time. But read access can still be + // acquired by other threads until the reserved write access is actually acquired. setAccess(getAccessManager().reserveWriteAccess(this)); - // retrieve a container which contains all id of those entities + // Retrieve a container which contains all IDs of those entities // which are to be updated. execute(new RetrieveFullEntityTransaction(oldContainer), getAccess()); - // retrieve all entity which are to be deleted. + // Retrieve all entities which are to be deleted. execute(new RetrieveFullEntityTransaction(deleteContainer), getAccess()); // Check if any updates are to be processed. @@ -282,7 +280,8 @@ public class WriteTransaction extends Transaction<WritableContainer> } /** Check if the user has all permissions */ - public void checkPermissions(final EntityInterface entity, final Set<Permission> permissions) { + public static void checkPermissions( + final EntityInterface entity, final Set<Permission> permissions) { for (final Permission p : permissions) { entity.checkPermission(p); } diff --git a/src/main/java/org/caosdb/server/utils/EntityStatus.java b/src/main/java/org/caosdb/server/utils/EntityStatus.java index ef8bdc10..6687622c 100644 --- a/src/main/java/org/caosdb/server/utils/EntityStatus.java +++ b/src/main/java/org/caosdb/server/utils/EntityStatus.java @@ -4,6 +4,8 @@ * * Copyright (C) 2018 Research Group Biomedical Physics, * Max-Planck-Institute for Dynamics and Self-Organization Göttingen + * Copyright (C) 2021 Indiscale GmbH <info@indiscale.com> + * Copyright (C) 2021 Daniel Hornung <d.hornung@indiscale.com> * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as @@ -23,18 +25,31 @@ package org.caosdb.server.utils; /** - * IGNORE - This instance must be ignored during further processing. <br> - * VALID - This instance has a final ID and has been synchronized with the database. <br> - * WRITTEN - This instance has been written successfully to the database. It has a final ID. <br> - * QUALIFIED - This instance has a provisional or final ID, represents a well-formed entity, and any - * referenced entities (by a reference property) have status QUALIFIED or VALID. QUALIFIED - This - * instance has been checked and is not qualified to be processed further (i.e. to be inserted, - * updated, deleted) DELETED - This instance has been deleted recently. CORRUPT - This instance has - * been retrieved from the database, but though something turned out to be wrong with it. - * NONEXISTENT - This instance has been called (via id or something) but it doesn't exist. + * The order of the EntityStatus values matters, in that everything later than "QUALIFIED" also + * counts as qualified. + * + * <p> + * + * <ul> + * <li>IGNORE - This instance must be ignored during further processing. + * <li>UNQUALIFIED - This instance has been checked and is not qualified to be processed further + * (i.e. to be inserted, updated, deleted) + * <li>DELETED - This instance has been deleted recently. + * <li>NONEXISTENT - This instance has been called (via id or something) but it doesn't exist. + * <li>QUALIFIED - This instance has a provisional or final ID, represents a well-formed entity, + * and any referenced entities (by a reference property) have status QUALIFIED or VALID. Every + * status after this one also counts as QUALIFIED. + * <li>VALID - This instance has a final ID and has been synchronized with the database. + * </ul> * * @author Timm Fitschen */ + +// TODO Can these comment lines be removed? +// * <li>WRITTEN - This instance has been written successfully to the database. It has a final ID. +// * // * <li>CORRUPT - This instance has +// * been retrieved from the database, but though something turned out to be wrong with it. + public enum EntityStatus { IGNORE, UNQUALIFIED, -- GitLab