Skip to content
Snippets Groups Projects
Commit 10199302 authored by Daniel Hornung's avatar Daniel Hornung
Browse files

DOC STY: Some documentation, typos, ...

parent b5541287
No related branches found
No related tags found
1 merge request!21Release v0.4.0
......@@ -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.
......
......@@ -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.
......
......@@ -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", "");
}
......
......@@ -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.
*
......
......@@ -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
......
......@@ -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
......
......@@ -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);
}
......
......@@ -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,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment