mirror of
https://github.com/PlaceholderAPI/PlaceholderAPI
synced 2025-02-05 15:55:28 +01:00
cacheLock and awaitLock
This commit is contained in:
parent
6e5d323213
commit
ab11e36206
@ -46,6 +46,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.stream.Collector;
|
import java.util.stream.Collector;
|
||||||
@ -76,8 +77,10 @@ public final class CloudExpansionManager {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private final Map<String, CloudExpansion> cache = new HashMap<>();
|
private final Map<String, CloudExpansion> cache = new HashMap<>();
|
||||||
|
private final ReentrantLock cacheLock = new ReentrantLock();
|
||||||
@NotNull
|
@NotNull
|
||||||
private final Map<String, CompletableFuture<File>> await = new ConcurrentHashMap<>();
|
private final Map<String, CompletableFuture<File>> await = new ConcurrentHashMap<>();
|
||||||
|
private final ReentrantLock awaitLock = new ReentrantLock();
|
||||||
|
|
||||||
static final ExecutorService ASYNC_EXECUTOR =
|
static final ExecutorService ASYNC_EXECUTOR =
|
||||||
Executors.newCachedThreadPool(
|
Executors.newCachedThreadPool(
|
||||||
@ -113,12 +116,19 @@ public final class CloudExpansionManager {
|
|||||||
@NotNull
|
@NotNull
|
||||||
@Unmodifiable
|
@Unmodifiable
|
||||||
public Map<String, CloudExpansion> getCloudExpansions() {
|
public Map<String, CloudExpansion> getCloudExpansions() {
|
||||||
|
cacheLock.lock();
|
||||||
|
try {
|
||||||
return ImmutableMap.copyOf(cache);
|
return ImmutableMap.copyOf(cache);
|
||||||
|
} finally {
|
||||||
|
cacheLock.unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Unmodifiable
|
@Unmodifiable
|
||||||
public Map<String, CloudExpansion> getCloudExpansionsInstalled() {
|
public Map<String, CloudExpansion> getCloudExpansionsInstalled() {
|
||||||
|
cacheLock.lock();
|
||||||
|
try {
|
||||||
if (cache.isEmpty()) {
|
if (cache.isEmpty()) {
|
||||||
return Collections.emptyMap();
|
return Collections.emptyMap();
|
||||||
}
|
}
|
||||||
@ -127,11 +137,16 @@ public final class CloudExpansionManager {
|
|||||||
.stream()
|
.stream()
|
||||||
.filter(CloudExpansion::hasExpansion)
|
.filter(CloudExpansion::hasExpansion)
|
||||||
.collect(INDEXED_NAME_COLLECTOR);
|
.collect(INDEXED_NAME_COLLECTOR);
|
||||||
|
} finally {
|
||||||
|
cacheLock.unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Unmodifiable
|
@Unmodifiable
|
||||||
public Map<String, CloudExpansion> getCloudExpansionsByAuthor(@NotNull final String author) {
|
public Map<String, CloudExpansion> getCloudExpansionsByAuthor(@NotNull final String author) {
|
||||||
|
cacheLock.lock();
|
||||||
|
try {
|
||||||
if (cache.isEmpty()) {
|
if (cache.isEmpty()) {
|
||||||
return Collections.emptyMap();
|
return Collections.emptyMap();
|
||||||
}
|
}
|
||||||
@ -140,12 +155,20 @@ public final class CloudExpansionManager {
|
|||||||
.stream()
|
.stream()
|
||||||
.filter(expansion -> author.equalsIgnoreCase(expansion.getAuthor()))
|
.filter(expansion -> author.equalsIgnoreCase(expansion.getAuthor()))
|
||||||
.collect(INDEXED_NAME_COLLECTOR);
|
.collect(INDEXED_NAME_COLLECTOR);
|
||||||
|
} finally {
|
||||||
|
cacheLock.unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Unmodifiable
|
@Unmodifiable
|
||||||
public Set<String> getCloudExpansionAuthors() {
|
public Set<String> getCloudExpansionAuthors() {
|
||||||
|
cacheLock.lock();
|
||||||
|
try {
|
||||||
return cache.values().stream().map(CloudExpansion::getAuthor).collect(Collectors.toSet());
|
return cache.values().stream().map(CloudExpansion::getAuthor).collect(Collectors.toSet());
|
||||||
|
} finally {
|
||||||
|
cacheLock.unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCloudExpansionAuthorCount() {
|
public int getCloudExpansionAuthorCount() {
|
||||||
@ -163,14 +186,29 @@ public final class CloudExpansionManager {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Optional<CloudExpansion> findCloudExpansionByName(@NotNull final String name) {
|
public Optional<CloudExpansion> findCloudExpansionByName(@NotNull final String name) {
|
||||||
|
cacheLock.lock();
|
||||||
|
try {
|
||||||
return Optional.ofNullable(cache.get(toIndexName(name)));
|
return Optional.ofNullable(cache.get(toIndexName(name)));
|
||||||
|
} finally {
|
||||||
|
cacheLock.unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clean() {
|
public void clean() {
|
||||||
|
cacheLock.lock();
|
||||||
|
try {
|
||||||
cache.clear();
|
cache.clear();
|
||||||
|
} finally {
|
||||||
|
cacheLock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
awaitLock.lock();
|
||||||
|
try {
|
||||||
await.values().forEach(future -> future.cancel(true));
|
await.values().forEach(future -> future.cancel(true));
|
||||||
await.clear();
|
await.clear();
|
||||||
|
} finally {
|
||||||
|
awaitLock.unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fetch(final boolean allowUnverified) {
|
public void fetch(final boolean allowUnverified) {
|
||||||
@ -231,7 +269,12 @@ public final class CloudExpansionManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cacheLock.lock();
|
||||||
|
try {
|
||||||
cache.put(toIndexName(expansion), expansion);
|
cache.put(toIndexName(expansion), expansion);
|
||||||
|
} finally {
|
||||||
|
cacheLock.unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
// ugly swallowing of every throwable, but we have to be defensive
|
// ugly swallowing of every throwable, but we have to be defensive
|
||||||
@ -244,13 +287,24 @@ public final class CloudExpansionManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDownloading(@NotNull final CloudExpansion expansion) {
|
public boolean isDownloading(@NotNull final CloudExpansion expansion) {
|
||||||
|
awaitLock.lock();
|
||||||
|
try {
|
||||||
return await.containsKey(toIndexName(expansion));
|
return await.containsKey(toIndexName(expansion));
|
||||||
|
} finally {
|
||||||
|
awaitLock.unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public CompletableFuture<File> downloadExpansion(@NotNull final CloudExpansion expansion,
|
public CompletableFuture<File> downloadExpansion(@NotNull final CloudExpansion expansion,
|
||||||
@NotNull final CloudExpansion.Version version) {
|
@NotNull final CloudExpansion.Version version) {
|
||||||
final CompletableFuture<File> previous = await.get(toIndexName(expansion));
|
CompletableFuture<File> previous;
|
||||||
|
awaitLock.lock();
|
||||||
|
try {
|
||||||
|
previous = await.get(toIndexName(expansion));
|
||||||
|
} finally {
|
||||||
|
awaitLock.unlock();
|
||||||
|
}
|
||||||
if (previous != null) {
|
if (previous != null) {
|
||||||
return previous;
|
return previous;
|
||||||
}
|
}
|
||||||
@ -269,7 +323,12 @@ public final class CloudExpansionManager {
|
|||||||
}, ASYNC_EXECUTOR);
|
}, ASYNC_EXECUTOR);
|
||||||
|
|
||||||
download.whenCompleteAsync((value, exception) -> {
|
download.whenCompleteAsync((value, exception) -> {
|
||||||
|
awaitLock.lock();
|
||||||
|
try {
|
||||||
await.remove(toIndexName(expansion));
|
await.remove(toIndexName(expansion));
|
||||||
|
} finally {
|
||||||
|
awaitLock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
if (exception != null) {
|
if (exception != null) {
|
||||||
plugin.getLogger().log(Level.SEVERE,
|
plugin.getLogger().log(Level.SEVERE,
|
||||||
@ -277,7 +336,12 @@ public final class CloudExpansionManager {
|
|||||||
}
|
}
|
||||||
}, ASYNC_EXECUTOR);
|
}, ASYNC_EXECUTOR);
|
||||||
|
|
||||||
|
awaitLock.lock();
|
||||||
|
try {
|
||||||
await.put(toIndexName(expansion), download);
|
await.put(toIndexName(expansion), download);
|
||||||
|
} finally {
|
||||||
|
awaitLock.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
return download;
|
return download;
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,6 @@ public final class Futures {
|
|||||||
@NotNull
|
@NotNull
|
||||||
private static <T> List<T> awaitCompletion(
|
private static <T> List<T> awaitCompletion(
|
||||||
@NotNull final Collection<CompletableFuture<T>> futures) {
|
@NotNull final Collection<CompletableFuture<T>> futures) {
|
||||||
// TODO: Calling CompletableFuture#join is bad. Find a way to optimise this whole class
|
|
||||||
return futures.stream().map(CompletableFuture::join).collect(Collectors.toList());
|
return futures.stream().map(CompletableFuture::join).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user