diff --git a/geowebcache/core/src/main/java/org/geowebcache/locks/MemoryLockProvider.java b/geowebcache/core/src/main/java/org/geowebcache/locks/MemoryLockProvider.java index 55a814c2a..d3d15e248 100644 --- a/geowebcache/core/src/main/java/org/geowebcache/locks/MemoryLockProvider.java +++ b/geowebcache/core/src/main/java/org/geowebcache/locks/MemoryLockProvider.java @@ -14,26 +14,26 @@ */ package org.geowebcache.locks; -import org.geotools.util.logging.Logging; - import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Level; import java.util.logging.Logger; +import org.geotools.util.logging.Logging; /** * An in memory lock provider. - *
- * This provider does not constrain the number of locks that can be held at any given time. - * Because any one thread can hold multiple locks at a time, a more appropriate approach - * to constraining resource usage would be to limit the number of concurrent threads instead. - *
- * One objective of this class is to support - * nested locking scenarios. This class used to use a striped lock algorithm which - * would cause deadlocks for nested locking because of the non-predictable manner in - * which any lock can be arbitrarily locked by another unrelated lock. An example use case of - * nested locks, in pseudocode, would be: + * + *
This provider does not constrain the number of locks that can be held at any given time. + * Because any one thread can hold multiple locks at a time, a more appropriate approach to + * constraining resource usage would be to limit the number of concurrent threads instead. + * + *
One objective of this class is to support nested locking + * scenarios. This class used to use a striped lock algorithm which would cause deadlocks for + * nested locking because of the non-predictable manner in which any lock can be arbitrarily locked + * by another unrelated lock. An example use case of nested locks, in pseudocode, would be: + * *
* lock(metatile); * try { @@ -54,7 +54,7 @@ */ public class MemoryLockProvider implements LockProvider { - private final static Logger LOGGER = Logging.getLogger(MemoryLockProvider.class.getName()); + private static final Logger LOGGER = Logging.getLogger(MemoryLockProvider.class.getName()); ConcurrentHashMaplockAndCounters = new ConcurrentHashMap<>(); @@ -93,8 +93,10 @@ public void release() { // Attempt to remove lock if no other thread is waiting for it if (lockAndCounter.counter.decrementAndGet() == 0) { - // Try to remove the lock, but we have to check the count AGAIN inside of "compute" - // so that we know it hasn't been incremented since the if-statement above was evaluated + // Try to remove the lock, but we have to check the count AGAIN inside of + // "compute" + // so that we know it hasn't been incremented since the if-statement above + // was evaluated lockAndCounters.compute( lockKey, (key, existingLockAndCounter) -> { @@ -113,8 +115,8 @@ public void release() { } /** - * A ReentrantLock with a counter to track how many threads are waiting on this lock - * so we know if it's safe to remove it during a release. + * A ReentrantLock with a counter to track how many threads are waiting on this lock so we know + * if it's safe to remove it during a release. */ private static class LockAndCounter { private final java.util.concurrent.locks.Lock lock = new ReentrantLock(); diff --git a/geowebcache/core/src/main/java/org/geowebcache/storage/blobstore/file/FileBlobStore.java b/geowebcache/core/src/main/java/org/geowebcache/storage/blobstore/file/FileBlobStore.java index 39f3b18d5..0d57555d5 100644 --- a/geowebcache/core/src/main/java/org/geowebcache/storage/blobstore/file/FileBlobStore.java +++ b/geowebcache/core/src/main/java/org/geowebcache/storage/blobstore/file/FileBlobStore.java @@ -14,7 +14,6 @@ */ package org.geowebcache.storage.blobstore.file; -import static java.util.Objects.isNull; import static org.geowebcache.storage.blobstore.file.FilePathUtils.filteredGridSetId; import static org.geowebcache.storage.blobstore.file.FilePathUtils.filteredLayerName; import static org.geowebcache.util.FileUtils.listFilesNullSafe; @@ -71,7 +70,12 @@ /** See BlobStore interface description for details */ public class FileBlobStore implements BlobStore { - interface Writer { + /** + * Interface for writing files. This is used to abstract the writing of files to allow different + * types of file writes, while keeping the same general machinery (write on temp file, rename to + * final file). + */ + interface FileWriter { void write(File file) throws IOException; } @@ -526,10 +530,9 @@ public void put(TileObject stObj) throws StorageException { private void putParametersMetadata( String layerName, String parametersId, Map parameters) throws StorageException { - assert (isNull(parametersId) == isNull(parameters)); - if (isNull(parametersId)) { - return; - } + // check if we even need to use any IO + if (parametersId == null || parameters == null || parameters.isEmpty()) return; + File parametersFile = parametersFile(layerName, parametersId); if (parametersFile.exists()) return; @@ -606,7 +609,8 @@ private void writeTile(File target, TileObject stObj, boolean existed) throws St * * @throws StorageException */ - private void writeFile(File target, boolean existed, Writer writer) throws StorageException { + private void writeFile(File target, boolean existed, FileWriter writer) + throws StorageException { // first write to temp file tmp.mkdirs(); File temp = new File(tmp, tmpGenerator.newName()); @@ -769,6 +773,18 @@ public boolean deleteByParametersId(String layerName, String parametersId) // delete the parameter file parametersFile(layerName, parametersId).delete(); + // clean up from the legacy metadata storage as well, if necessary + try { + layerMetadata.putEntry(layerName, "parameters." + parametersId, null); + } catch (IOException e) { + log.log( + Level.WARNING, + String.format( + "Failed to clean up metadata for parameters %s in layer %s", + parametersId, layerName), + e); + } + // delete the caches File[] parameterCaches = listFilesNullSafe(