Refactor the way holder caches are invalidated in order to improve consistency (#734)
This commit is contained in:
parent
b8a1871cf1
commit
a6facf7492
@ -55,11 +55,6 @@ public class BukkitConfigAdapter extends AbstractConfigurationAdapter implements
|
|||||||
this.configuration = YamlConfiguration.loadConfiguration(this.file);
|
this.configuration = YamlConfiguration.loadConfiguration(this.file);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean contains(String path) {
|
|
||||||
return this.configuration.contains(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getString(String path, String def) {
|
public String getString(String path, String def) {
|
||||||
return this.configuration.getString(path, def);
|
return this.configuration.getString(path, def);
|
||||||
|
@ -403,7 +403,7 @@ public class VaultPermissionHook extends AbstractVaultPermission {
|
|||||||
void holderSave(PermissionHolder holder) {
|
void holderSave(PermissionHolder holder) {
|
||||||
if (holder.getType().isUser()) {
|
if (holder.getType().isUser()) {
|
||||||
User u = (User) holder;
|
User u = (User) holder;
|
||||||
this.plugin.getStorage().saveUser(u).thenRunAsync(() -> u.getRefreshBuffer().request(), this.plugin.getBootstrap().getScheduler().async());
|
this.plugin.getStorage().saveUser(u).thenRunAsync(() -> u.reloadCachedData(), this.plugin.getBootstrap().getScheduler().async());
|
||||||
}
|
}
|
||||||
if (holder.getType().isGroup()) {
|
if (holder.getType().isGroup()) {
|
||||||
Group g = (Group) holder;
|
Group g = (Group) holder;
|
||||||
|
@ -61,11 +61,6 @@ public class BungeeConfigAdapter extends AbstractConfigurationAdapter implements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean contains(String path) {
|
|
||||||
return this.configuration.contains(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getString(String path, String def) {
|
public String getString(String path, String def) {
|
||||||
return this.configuration.getString(path, def);
|
return this.configuration.getString(path, def);
|
||||||
|
@ -98,7 +98,7 @@ public class ApiPermissionHolder implements me.lucko.luckperms.api.PermissionHol
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Void> refreshCachedData() {
|
public CompletableFuture<Void> refreshCachedData() {
|
||||||
return this.handle.getRefreshBuffer().request();
|
return this.handle.reloadCachedData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
|
@ -99,7 +99,7 @@ public final class ApiUser extends ApiPermissionHolder implements me.lucko.luckp
|
|||||||
@Override
|
@Override
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public void refreshPermissions() {
|
public void refreshPermissions() {
|
||||||
this.handle.getRefreshBuffer().requestDirectly();
|
this.handle.reloadCachedData().join();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -25,9 +25,9 @@
|
|||||||
|
|
||||||
package me.lucko.luckperms.common.caching;
|
package me.lucko.luckperms.common.caching;
|
||||||
|
|
||||||
|
import com.github.benmanes.caffeine.cache.AsyncLoadingCache;
|
||||||
import com.github.benmanes.caffeine.cache.CacheLoader;
|
import com.github.benmanes.caffeine.cache.CacheLoader;
|
||||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
import com.github.benmanes.caffeine.cache.Caffeine;
|
||||||
import com.github.benmanes.caffeine.cache.LoadingCache;
|
|
||||||
|
|
||||||
import me.lucko.luckperms.api.ChatMetaType;
|
import me.lucko.luckperms.api.ChatMetaType;
|
||||||
import me.lucko.luckperms.api.Contexts;
|
import me.lucko.luckperms.api.Contexts;
|
||||||
@ -43,7 +43,6 @@ import me.lucko.luckperms.common.calculators.PermissionCalculatorMetadata;
|
|||||||
import me.lucko.luckperms.common.metastacking.SimpleMetaStack;
|
import me.lucko.luckperms.common.metastacking.SimpleMetaStack;
|
||||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -51,6 +50,7 @@ import java.util.concurrent.CompletableFuture;
|
|||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract implementation of {@link CachedData}.
|
* Abstract implementation of {@link CachedData}.
|
||||||
@ -65,16 +65,16 @@ public abstract class AbstractCachedData implements CachedData {
|
|||||||
/**
|
/**
|
||||||
* The cache used for {@link PermissionCache} instances.
|
* The cache used for {@link PermissionCache} instances.
|
||||||
*/
|
*/
|
||||||
private final LoadingCache<Contexts, PermissionCache> permission = Caffeine.newBuilder()
|
private final AsyncLoadingCache<Contexts, PermissionCache> permission = Caffeine.newBuilder()
|
||||||
.expireAfterAccess(2, TimeUnit.MINUTES)
|
.expireAfterAccess(2, TimeUnit.MINUTES)
|
||||||
.build(new PermissionCacheLoader());
|
.buildAsync(new PermissionCacheLoader());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The cache used for {@link MetaCache} instances.
|
* The cache used for {@link MetaCache} instances.
|
||||||
*/
|
*/
|
||||||
private final LoadingCache<MetaContexts, MetaCache> meta = Caffeine.newBuilder()
|
private final AsyncLoadingCache<MetaContexts, MetaCache> meta = Caffeine.newBuilder()
|
||||||
.expireAfterAccess(2, TimeUnit.MINUTES)
|
.expireAfterAccess(2, TimeUnit.MINUTES)
|
||||||
.build(new MetaCacheLoader());
|
.buildAsync(new MetaCacheLoader());
|
||||||
|
|
||||||
public AbstractCachedData(LuckPermsPlugin plugin) {
|
public AbstractCachedData(LuckPermsPlugin plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
@ -190,7 +190,7 @@ public abstract class AbstractCachedData implements CachedData {
|
|||||||
Objects.requireNonNull(contexts, "contexts");
|
Objects.requireNonNull(contexts, "contexts");
|
||||||
|
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
return this.permission.get(contexts);
|
return this.permission.get(contexts).join();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@ -199,7 +199,7 @@ public abstract class AbstractCachedData implements CachedData {
|
|||||||
Objects.requireNonNull(contexts, "contexts");
|
Objects.requireNonNull(contexts, "contexts");
|
||||||
|
|
||||||
//noinspection ConstantConditions
|
//noinspection ConstantConditions
|
||||||
return this.meta.get(contexts);
|
return this.meta.get(contexts).join();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@ -233,13 +233,13 @@ public abstract class AbstractCachedData implements CachedData {
|
|||||||
@Override
|
@Override
|
||||||
public void recalculatePermissions(@Nonnull Contexts contexts) {
|
public void recalculatePermissions(@Nonnull Contexts contexts) {
|
||||||
Objects.requireNonNull(contexts, "contexts");
|
Objects.requireNonNull(contexts, "contexts");
|
||||||
this.permission.refresh(contexts);
|
this.permission.synchronous().refresh(contexts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void recalculateMeta(@Nonnull MetaContexts contexts) {
|
public void recalculateMeta(@Nonnull MetaContexts contexts) {
|
||||||
Objects.requireNonNull(contexts, "contexts");
|
Objects.requireNonNull(contexts, "contexts");
|
||||||
this.meta.refresh(contexts);
|
this.meta.synchronous().refresh(contexts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -254,13 +254,19 @@ public abstract class AbstractCachedData implements CachedData {
|
|||||||
Objects.requireNonNull(contexts, "contexts");
|
Objects.requireNonNull(contexts, "contexts");
|
||||||
|
|
||||||
// get the previous value - to use when recalculating
|
// get the previous value - to use when recalculating
|
||||||
PermissionCache previous = this.permission.getIfPresent(contexts);
|
CompletableFuture<PermissionCache> previous = this.permission.getIfPresent(contexts);
|
||||||
|
|
||||||
// invalidate the entry
|
// invalidate any previous setting
|
||||||
this.permission.invalidate(contexts);
|
this.permission.synchronous().invalidate(contexts);
|
||||||
|
|
||||||
// repopulate the cache
|
// if the previous value is already calculated, use it when recalculating.
|
||||||
return CompletableFuture.supplyAsync(() -> this.permission.get(contexts, c -> calculatePermissions(c, previous)));
|
PermissionCache value = getIfReady(previous);
|
||||||
|
if (value != null) {
|
||||||
|
return this.permission.get(contexts, c -> calculatePermissions(c, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise, just calculate a new value
|
||||||
|
return this.permission.get(contexts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@ -269,13 +275,19 @@ public abstract class AbstractCachedData implements CachedData {
|
|||||||
Objects.requireNonNull(contexts, "contexts");
|
Objects.requireNonNull(contexts, "contexts");
|
||||||
|
|
||||||
// get the previous value - to use when recalculating
|
// get the previous value - to use when recalculating
|
||||||
MetaCache previous = this.meta.getIfPresent(contexts);
|
CompletableFuture<MetaCache> previous = this.meta.getIfPresent(contexts);
|
||||||
|
|
||||||
// invalidate the entry
|
// invalidate any previous setting
|
||||||
this.meta.invalidate(contexts);
|
this.meta.synchronous().invalidate(contexts);
|
||||||
|
|
||||||
// repopulate the cache
|
// if the previous value is already calculated, use it when recalculating.
|
||||||
return CompletableFuture.supplyAsync(() -> this.meta.get(contexts, c -> calculateMeta(c, previous)));
|
MetaCache value = getIfReady(previous);
|
||||||
|
if (value != null) {
|
||||||
|
return this.meta.get(contexts, c -> calculateMeta(c, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise, just calculate a new value
|
||||||
|
return this.meta.get(contexts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@ -287,30 +299,34 @@ public abstract class AbstractCachedData implements CachedData {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void recalculatePermissions() {
|
public void recalculatePermissions() {
|
||||||
Set<Contexts> keys = this.permission.asMap().keySet();
|
Set<Contexts> keys = this.permission.synchronous().asMap().keySet();
|
||||||
keys.forEach(this::recalculatePermissions);
|
keys.forEach(this::recalculatePermissions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void recalculateMeta() {
|
public void recalculateMeta() {
|
||||||
Set<MetaContexts> keys = this.meta.asMap().keySet();
|
Set<MetaContexts> keys = this.meta.synchronous().asMap().keySet();
|
||||||
keys.forEach(this::recalculateMeta);
|
keys.forEach(this::recalculateMeta);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Void> reloadPermissions() {
|
public CompletableFuture<Void> reloadPermissions() {
|
||||||
Set<Contexts> keys = new HashSet<>(this.permission.asMap().keySet());
|
Set<Contexts> keys = this.permission.synchronous().asMap().keySet();
|
||||||
return CompletableFuture.allOf(keys.stream().map(this::reloadPermissions).toArray(CompletableFuture[]::new));
|
return CompletableFuture.allOf(keys.stream().map(this::reloadPermissions).toArray(CompletableFuture[]::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public CompletableFuture<Void> reloadMeta() {
|
public CompletableFuture<Void> reloadMeta() {
|
||||||
Set<MetaContexts> keys = new HashSet<>(this.meta.asMap().keySet());
|
Set<MetaContexts> keys = this.meta.synchronous().asMap().keySet();
|
||||||
return CompletableFuture.allOf(keys.stream().map(this::reloadMeta).toArray(CompletableFuture[]::new));
|
return CompletableFuture.allOf(keys.stream().map(this::reloadMeta).toArray(CompletableFuture[]::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CompletableFuture<Void> reloadAll() {
|
||||||
|
return CompletableFuture.allOf(reloadPermissions(), reloadMeta());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void preCalculate(@Nonnull Contexts contexts) {
|
public void preCalculate(@Nonnull Contexts contexts) {
|
||||||
Objects.requireNonNull(contexts, "contexts");
|
Objects.requireNonNull(contexts, "contexts");
|
||||||
@ -324,34 +340,45 @@ public abstract class AbstractCachedData implements CachedData {
|
|||||||
@Override
|
@Override
|
||||||
public void invalidatePermissions(@Nonnull Contexts contexts) {
|
public void invalidatePermissions(@Nonnull Contexts contexts) {
|
||||||
Objects.requireNonNull(contexts, "contexts");
|
Objects.requireNonNull(contexts, "contexts");
|
||||||
this.permission.invalidate(contexts);
|
this.permission.synchronous().invalidate(contexts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invalidateMeta(@Nonnull MetaContexts contexts) {
|
public void invalidateMeta(@Nonnull MetaContexts contexts) {
|
||||||
Objects.requireNonNull(contexts, "contexts");
|
Objects.requireNonNull(contexts, "contexts");
|
||||||
this.meta.invalidate(contexts);
|
this.meta.synchronous().invalidate(contexts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invalidateMeta(@Nonnull Contexts contexts) {
|
public void invalidateMeta(@Nonnull Contexts contexts) {
|
||||||
Objects.requireNonNull(contexts, "contexts");
|
Objects.requireNonNull(contexts, "contexts");
|
||||||
this.meta.invalidate(getDefaultMetaContexts(contexts));
|
this.meta.synchronous().invalidate(getDefaultMetaContexts(contexts));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invalidatePermissionCalculators() {
|
public void invalidatePermissionCalculators() {
|
||||||
this.permission.asMap().values().forEach(PermissionCache::invalidateCache);
|
this.permission.synchronous().asMap().values().forEach(PermissionCache::invalidateCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void invalidateCaches() {
|
public void invalidateCaches() {
|
||||||
this.permission.invalidateAll();
|
this.permission.synchronous().invalidateAll();
|
||||||
this.meta.invalidateAll();
|
this.meta.synchronous().invalidateAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void doCacheCleanup() {
|
public void doCacheCleanup() {
|
||||||
this.permission.cleanUp();
|
this.permission.synchronous().cleanUp();
|
||||||
this.meta.cleanUp();
|
this.meta.synchronous().cleanUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isReady(@Nullable CompletableFuture<?> future) {
|
||||||
|
return (future != null) && future.isDone()
|
||||||
|
&& !future.isCompletedExceptionally()
|
||||||
|
&& (future.join() != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Returns the current value or null if either not done or failed. */
|
||||||
|
private static <V> V getIfReady(@Nullable CompletableFuture<V> future) {
|
||||||
|
return isReady(future) ? future.join() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private final class PermissionCacheLoader implements CacheLoader<Contexts, PermissionCache> {
|
private final class PermissionCacheLoader implements CacheLoader<Contexts, PermissionCache> {
|
||||||
|
@ -108,7 +108,7 @@ public final class StorageAssistant {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
user.getRefreshBuffer().requestDirectly();
|
user.reloadCachedData().join();
|
||||||
|
|
||||||
Optional<InternalMessagingService> messagingService = plugin.getMessagingService();
|
Optional<InternalMessagingService> messagingService = plugin.getMessagingService();
|
||||||
if (messagingService.isPresent() && plugin.getConfiguration().get(ConfigKeys.AUTO_PUSH_UPDATES)) {
|
if (messagingService.isPresent() && plugin.getConfiguration().get(ConfigKeys.AUTO_PUSH_UPDATES)) {
|
||||||
|
@ -36,8 +36,6 @@ public interface ConfigurationAdapter {
|
|||||||
|
|
||||||
void reload();
|
void reload();
|
||||||
|
|
||||||
boolean contains(String path);
|
|
||||||
|
|
||||||
String getString(String path, String def);
|
String getString(String path, String def);
|
||||||
|
|
||||||
int getInt(String path, int def);
|
int getInt(String path, int def);
|
||||||
|
@ -29,7 +29,6 @@ import me.lucko.luckperms.api.Node;
|
|||||||
import me.lucko.luckperms.api.context.ContextSet;
|
import me.lucko.luckperms.api.context.ContextSet;
|
||||||
import me.lucko.luckperms.api.nodetype.types.DisplayNameType;
|
import me.lucko.luckperms.api.nodetype.types.DisplayNameType;
|
||||||
import me.lucko.luckperms.common.api.delegates.model.ApiGroup;
|
import me.lucko.luckperms.common.api.delegates.model.ApiGroup;
|
||||||
import me.lucko.luckperms.common.buffers.BufferedRequest;
|
|
||||||
import me.lucko.luckperms.common.buffers.Cache;
|
import me.lucko.luckperms.common.buffers.Cache;
|
||||||
import me.lucko.luckperms.common.caching.GroupCachedData;
|
import me.lucko.luckperms.common.caching.GroupCachedData;
|
||||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||||
@ -61,34 +60,66 @@ public class Group extends PermissionHolder implements Identifiable<String> {
|
|||||||
*/
|
*/
|
||||||
private final GroupCachedData cachedData;
|
private final GroupCachedData cachedData;
|
||||||
|
|
||||||
/**
|
|
||||||
* The group's cached data refresh buffer
|
|
||||||
*/
|
|
||||||
private final GroupRefreshBuffer refreshBuffer;
|
|
||||||
|
|
||||||
public Group(String name, LuckPermsPlugin plugin) {
|
public Group(String name, LuckPermsPlugin plugin) {
|
||||||
super(name, plugin);
|
super(plugin);
|
||||||
this.name = name.toLowerCase();
|
this.name = name.toLowerCase();
|
||||||
|
|
||||||
this.refreshBuffer = new GroupRefreshBuffer(plugin, this);
|
|
||||||
this.cachedData = new GroupCachedData(this);
|
this.cachedData = new GroupCachedData(this);
|
||||||
getPlugin().getEventFactory().handleGroupCacheLoad(this, this.cachedData);
|
getPlugin().getEventFactory().handleGroupCacheLoad(this, this.cachedData);
|
||||||
|
|
||||||
// invalidate our caches when data is updated
|
|
||||||
getStateListeners().add(this.refreshBuffer::request);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void invalidateCache() {
|
protected void invalidateCache() {
|
||||||
|
super.invalidateCache();
|
||||||
|
|
||||||
|
// invalidate our caches
|
||||||
this.weightCache.invalidate();
|
this.weightCache.invalidate();
|
||||||
this.displayNameCache.invalidate();
|
this.displayNameCache.invalidate();
|
||||||
super.invalidateCache();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// name getters
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return this.name;
|
return this.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getObjectName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getFriendlyName() {
|
||||||
|
Optional<String> dn = getDisplayName();
|
||||||
|
return dn.map(s -> this.name + " (" + s + ")").orElse(this.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<String> getDisplayName() {
|
||||||
|
return this.displayNameCache.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a display name value exactly matching a specific context.
|
||||||
|
*
|
||||||
|
* <p>Note that the behaviour of {@link #getDisplayName()} is not the same as this.</p>
|
||||||
|
*
|
||||||
|
* @param contextSet the contexts to lookup in
|
||||||
|
* @return the display name
|
||||||
|
*/
|
||||||
|
public Optional<String> getDisplayName(ContextSet contextSet) {
|
||||||
|
for (Node n : getData(NodeMapType.ENDURING).immutable().get(contextSet.makeImmutable())) {
|
||||||
|
Optional<DisplayNameType> displayName = n.getTypeData(DisplayNameType.KEY);
|
||||||
|
if (displayName.isPresent()) {
|
||||||
|
return Optional.of(displayName.get().getDisplayName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
public ApiGroup getApiDelegate() {
|
public ApiGroup getApiDelegate() {
|
||||||
return this.apiDelegate;
|
return this.apiDelegate;
|
||||||
}
|
}
|
||||||
@ -98,36 +129,6 @@ public class Group extends PermissionHolder implements Identifiable<String> {
|
|||||||
return this.cachedData;
|
return this.cachedData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public BufferedRequest<Void> getRefreshBuffer() {
|
|
||||||
return this.refreshBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getId() {
|
|
||||||
return this.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Optional<String> getDisplayName() {
|
|
||||||
return this.displayNameCache.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Optional<String> getDisplayName(ContextSet contextSet) {
|
|
||||||
for (Node n : getData(NodeMapType.ENDURING).immutable().get(contextSet.makeImmutable())) {
|
|
||||||
Optional<DisplayNameType> displayName = n.getTypeData(DisplayNameType.KEY);
|
|
||||||
if (displayName.isPresent()) {
|
|
||||||
return Optional.of(displayName.get().getDisplayName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getFriendlyName() {
|
|
||||||
Optional<String> dn = getDisplayName();
|
|
||||||
return dn.map(s -> this.name + " (" + s + ")").orElse(this.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OptionalInt getWeight() {
|
public OptionalInt getWeight() {
|
||||||
return this.weightCache.get();
|
return this.weightCache.get();
|
||||||
@ -138,11 +139,10 @@ public class Group extends PermissionHolder implements Identifiable<String> {
|
|||||||
return HolderType.GROUP;
|
return HolderType.GROUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
private CompletableFuture<Void> reloadCachedData() {
|
@Override
|
||||||
return CompletableFuture.allOf(
|
public CompletableFuture<Void> reloadCachedData() {
|
||||||
this.cachedData.reloadPermissions(),
|
return this.cachedData.reloadAll()
|
||||||
this.cachedData.reloadMeta()
|
.thenAccept(n -> getPlugin().getEventFactory().handleGroupDataRecalculate(this, this.cachedData));
|
||||||
).thenAccept(n -> getPlugin().getEventFactory().handleGroupDataRecalculate(this, this.cachedData));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -163,18 +163,4 @@ public class Group extends PermissionHolder implements Identifiable<String> {
|
|||||||
return "Group(name=" + this.name + ")";
|
return "Group(name=" + this.name + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class GroupRefreshBuffer extends BufferedRequest<Void> {
|
|
||||||
private final Group group;
|
|
||||||
|
|
||||||
private GroupRefreshBuffer(LuckPermsPlugin plugin, Group group) {
|
|
||||||
super(50L, 5L, plugin.getBootstrap().getScheduler().async());
|
|
||||||
this.group = group;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Void perform() {
|
|
||||||
return this.group.reloadCachedData().join();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -40,9 +40,7 @@ import me.lucko.luckperms.api.StandardNodeEquality;
|
|||||||
import me.lucko.luckperms.api.Tristate;
|
import me.lucko.luckperms.api.Tristate;
|
||||||
import me.lucko.luckperms.api.context.ContextSet;
|
import me.lucko.luckperms.api.context.ContextSet;
|
||||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||||
import me.lucko.luckperms.common.buffers.BufferedRequest;
|
|
||||||
import me.lucko.luckperms.common.caching.HolderCachedData;
|
import me.lucko.luckperms.common.caching.HolderCachedData;
|
||||||
import me.lucko.luckperms.common.caching.handlers.StateListener;
|
|
||||||
import me.lucko.luckperms.common.caching.type.MetaAccumulator;
|
import me.lucko.luckperms.common.caching.type.MetaAccumulator;
|
||||||
import me.lucko.luckperms.common.config.ConfigKeys;
|
import me.lucko.luckperms.common.config.ConfigKeys;
|
||||||
import me.lucko.luckperms.common.inheritance.InheritanceComparator;
|
import me.lucko.luckperms.common.inheritance.InheritanceComparator;
|
||||||
@ -67,7 +65,7 @@ import java.util.OptionalInt;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.SortedSet;
|
import java.util.SortedSet;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.concurrent.locks.Lock;
|
import java.util.concurrent.locks.Lock;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
@ -95,18 +93,6 @@ import java.util.function.Predicate;
|
|||||||
*/
|
*/
|
||||||
public abstract class PermissionHolder {
|
public abstract class PermissionHolder {
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of this object.
|
|
||||||
*
|
|
||||||
* <p>Used as a base for identifying permission holding objects. Also acts
|
|
||||||
* as a method for preventing circular inheritance issues.</p>
|
|
||||||
*
|
|
||||||
* @see User#getUuid()
|
|
||||||
* @see Group#getName()
|
|
||||||
* @see #getObjectName()
|
|
||||||
*/
|
|
||||||
private final String objectName;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reference to the main plugin instance
|
* Reference to the main plugin instance
|
||||||
* @see #getPlugin()
|
* @see #getPlugin()
|
||||||
@ -146,18 +132,15 @@ public abstract class PermissionHolder {
|
|||||||
private final Comparator<Group> inheritanceComparator = InheritanceComparator.getFor(this);
|
private final Comparator<Group> inheritanceComparator = InheritanceComparator.getFor(this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A set of runnables which are called when this objects state changes.
|
* Creates a new instance
|
||||||
|
*
|
||||||
|
* @param plugin the plugin instance
|
||||||
*/
|
*/
|
||||||
private final Set<StateListener> stateListeners = ConcurrentHashMap.newKeySet();
|
protected PermissionHolder(LuckPermsPlugin plugin) {
|
||||||
|
|
||||||
protected PermissionHolder(String objectName, LuckPermsPlugin plugin) {
|
|
||||||
this.objectName = objectName;
|
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getObjectName() {
|
// getters
|
||||||
return this.objectName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LuckPermsPlugin getPlugin() {
|
public LuckPermsPlugin getPlugin() {
|
||||||
return this.plugin;
|
return this.plugin;
|
||||||
@ -167,52 +150,6 @@ public abstract class PermissionHolder {
|
|||||||
return this.ioLock;
|
return this.ioLock;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<StateListener> getStateListeners() {
|
|
||||||
return this.stateListeners;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void invalidateCache() {
|
|
||||||
this.enduringNodes.invalidate();
|
|
||||||
this.transientNodes.invalidate();
|
|
||||||
|
|
||||||
// Invalidate listeners
|
|
||||||
for (StateListener listener : this.stateListeners) {
|
|
||||||
try {
|
|
||||||
listener.onStateChange();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the friendly name of this permission holder (for use in commands, etc)
|
|
||||||
*
|
|
||||||
* @return the holders "friendly" name
|
|
||||||
*/
|
|
||||||
public abstract String getFriendlyName();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the holders cached data
|
|
||||||
*
|
|
||||||
* @return the holders cached data
|
|
||||||
*/
|
|
||||||
public abstract HolderCachedData<?> getCachedData();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the holders refresh buffer
|
|
||||||
*
|
|
||||||
* @return the holders refresh buffer
|
|
||||||
*/
|
|
||||||
public abstract BufferedRequest<Void> getRefreshBuffer();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the type of this PermissionHolder.
|
|
||||||
*
|
|
||||||
* @return this holders type
|
|
||||||
*/
|
|
||||||
public abstract HolderType getType();
|
|
||||||
|
|
||||||
public Comparator<Group> getInheritanceComparator() {
|
public Comparator<Group> getInheritanceComparator() {
|
||||||
return this.inheritanceComparator;
|
return this.inheritanceComparator;
|
||||||
}
|
}
|
||||||
@ -236,6 +173,51 @@ public abstract class PermissionHolder {
|
|||||||
return this.transientNodes;
|
return this.transientNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the unique name of this holder object.
|
||||||
|
*
|
||||||
|
* <p>Used as a base for identifying permission holding objects. Also acts
|
||||||
|
* as a method for preventing circular inheritance issues.</p>
|
||||||
|
*
|
||||||
|
* @return the object name
|
||||||
|
*/
|
||||||
|
public abstract String getObjectName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the friendly name of this permission holder (for use in commands, etc)
|
||||||
|
*
|
||||||
|
* @return the holders "friendly" name
|
||||||
|
*/
|
||||||
|
public abstract String getFriendlyName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the holders cached data
|
||||||
|
*
|
||||||
|
* @return the holders cached data
|
||||||
|
*/
|
||||||
|
public abstract HolderCachedData<?> getCachedData();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the type of this PermissionHolder.
|
||||||
|
*
|
||||||
|
* @return this holders type
|
||||||
|
*/
|
||||||
|
public abstract HolderType getType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reloads the holder's cached data.
|
||||||
|
*
|
||||||
|
* @return a future encapsulating the result
|
||||||
|
*/
|
||||||
|
public abstract CompletableFuture<Void> reloadCachedData();
|
||||||
|
|
||||||
|
protected void invalidateCache() {
|
||||||
|
this.enduringNodes.invalidate();
|
||||||
|
this.transientNodes.invalidate();
|
||||||
|
|
||||||
|
reloadCachedData();
|
||||||
|
}
|
||||||
|
|
||||||
public void setNodes(NodeMapType type, Set<Node> set) {
|
public void setNodes(NodeMapType type, Set<Node> set) {
|
||||||
getData(type).setContent(set);
|
getData(type).setContent(set);
|
||||||
invalidateCache();
|
invalidateCache();
|
||||||
|
@ -26,16 +26,18 @@
|
|||||||
package me.lucko.luckperms.common.model;
|
package me.lucko.luckperms.common.model;
|
||||||
|
|
||||||
import me.lucko.luckperms.api.Contexts;
|
import me.lucko.luckperms.api.Contexts;
|
||||||
import me.lucko.luckperms.common.buffers.BufferedRequest;
|
|
||||||
import me.lucko.luckperms.common.caching.UserCachedData;
|
import me.lucko.luckperms.common.caching.UserCachedData;
|
||||||
import me.lucko.luckperms.common.config.ConfigKeys;
|
import me.lucko.luckperms.common.config.ConfigKeys;
|
||||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||||
|
import me.lucko.luckperms.common.primarygroup.CachedPrimaryGroupHolder;
|
||||||
import me.lucko.luckperms.common.primarygroup.PrimaryGroupHolder;
|
import me.lucko.luckperms.common.primarygroup.PrimaryGroupHolder;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
public class User extends PermissionHolder implements Identifiable<UserIdentifier> {
|
public class User extends PermissionHolder implements Identifiable<UserIdentifier> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -46,6 +48,7 @@ public class User extends PermissionHolder implements Identifiable<UserIdentifie
|
|||||||
/**
|
/**
|
||||||
* The last known username of a player
|
* The last known username of a player
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
private String name = null;
|
private String name = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,14 +61,11 @@ public class User extends PermissionHolder implements Identifiable<UserIdentifie
|
|||||||
*/
|
*/
|
||||||
private final UserCachedData cachedData;
|
private final UserCachedData cachedData;
|
||||||
|
|
||||||
private final UserRefreshBuffer refreshBuffer;
|
|
||||||
|
|
||||||
public User(UUID uuid, String name, LuckPermsPlugin plugin) {
|
public User(UUID uuid, String name, LuckPermsPlugin plugin) {
|
||||||
super(uuid.toString(), plugin);
|
super(plugin);
|
||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
setName(name, false);
|
setName(name, false);
|
||||||
|
|
||||||
this.refreshBuffer = new UserRefreshBuffer(plugin, this);
|
|
||||||
this.primaryGroup = plugin.getConfiguration().get(ConfigKeys.PRIMARY_GROUP_CALCULATION).apply(this);
|
this.primaryGroup = plugin.getConfiguration().get(ConfigKeys.PRIMARY_GROUP_CALCULATION).apply(this);
|
||||||
|
|
||||||
this.cachedData = new UserCachedData(this);
|
this.cachedData = new UserCachedData(this);
|
||||||
@ -76,22 +76,27 @@ public class User extends PermissionHolder implements Identifiable<UserIdentifie
|
|||||||
this(uuid, null, plugin);
|
this(uuid, null, plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void invalidateCache() {
|
||||||
|
super.invalidateCache();
|
||||||
|
|
||||||
|
// invalidate our caches
|
||||||
|
if (this.primaryGroup instanceof CachedPrimaryGroupHolder) {
|
||||||
|
((CachedPrimaryGroupHolder) this.primaryGroup).invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public UUID getUuid() {
|
public UUID getUuid() {
|
||||||
return this.uuid;
|
return this.uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public PrimaryGroupHolder getPrimaryGroup() {
|
public Optional<String> getName() {
|
||||||
return this.primaryGroup;
|
return Optional.ofNullable(this.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserCachedData getCachedData() {
|
public String getObjectName() {
|
||||||
return this.cachedData;
|
return this.uuid.toString();
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BufferedRequest<Void> getRefreshBuffer() {
|
|
||||||
return this.refreshBuffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -99,8 +104,18 @@ public class User extends PermissionHolder implements Identifiable<UserIdentifie
|
|||||||
return UserIdentifier.of(this.uuid, this.name);
|
return UserIdentifier.of(this.uuid, this.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<String> getName() {
|
@Override
|
||||||
return Optional.ofNullable(this.name);
|
public String getFriendlyName() {
|
||||||
|
return this.name != null ? this.name : this.uuid.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UserCachedData getCachedData() {
|
||||||
|
return this.cachedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PrimaryGroupHolder getPrimaryGroup() {
|
||||||
|
return this.primaryGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -152,11 +167,6 @@ public class User extends PermissionHolder implements Identifiable<UserIdentifie
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getFriendlyName() {
|
|
||||||
return this.name != null ? this.name : this.uuid.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HolderType getType() {
|
public HolderType getType() {
|
||||||
return HolderType.USER;
|
return HolderType.USER;
|
||||||
@ -168,7 +178,7 @@ public class User extends PermissionHolder implements Identifiable<UserIdentifie
|
|||||||
*/
|
*/
|
||||||
public void preCalculateData() {
|
public void preCalculateData() {
|
||||||
// first try to refresh any existing permissions
|
// first try to refresh any existing permissions
|
||||||
this.refreshBuffer.requestDirectly();
|
reloadCachedData().join();
|
||||||
|
|
||||||
// pre-calc the allowall & global contexts
|
// pre-calc the allowall & global contexts
|
||||||
// since contexts change so frequently, it's not worth trying to calculate any more than this.
|
// since contexts change so frequently, it's not worth trying to calculate any more than this.
|
||||||
@ -176,11 +186,10 @@ public class User extends PermissionHolder implements Identifiable<UserIdentifie
|
|||||||
this.cachedData.preCalculate(Contexts.global());
|
this.cachedData.preCalculate(Contexts.global());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public CompletableFuture<Void> reloadCachedData() {
|
public CompletableFuture<Void> reloadCachedData() {
|
||||||
return CompletableFuture.allOf(
|
return this.cachedData.reloadAll()
|
||||||
this.cachedData.reloadPermissions(),
|
.thenAccept(n -> getPlugin().getEventFactory().handleUserDataRecalculate(this, this.cachedData));
|
||||||
this.cachedData.reloadMeta()
|
|
||||||
).thenAccept(n -> getPlugin().getEventFactory().handleUserDataRecalculate(this, this.cachedData));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -197,13 +206,6 @@ public class User extends PermissionHolder implements Identifiable<UserIdentifie
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void clearNodes(boolean giveDefault) {
|
|
||||||
super.clearNodes();
|
|
||||||
if (giveDefault) {
|
|
||||||
getPlugin().getUserManager().giveDefaultIfNeeded(this, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (o == this) return true;
|
if (o == this) return true;
|
||||||
@ -222,18 +224,4 @@ public class User extends PermissionHolder implements Identifiable<UserIdentifie
|
|||||||
return "User(uuid=" + this.uuid + ")";
|
return "User(uuid=" + this.uuid + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class UserRefreshBuffer extends BufferedRequest<Void> {
|
|
||||||
private final User user;
|
|
||||||
|
|
||||||
private UserRefreshBuffer(LuckPermsPlugin plugin, User user) {
|
|
||||||
super(50L, 5L, plugin.getBootstrap().getScheduler().async());
|
|
||||||
this.user = user;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Void perform() {
|
|
||||||
return this.user.reloadCachedData().join();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -26,16 +26,15 @@
|
|||||||
package me.lucko.luckperms.common.primarygroup;
|
package me.lucko.luckperms.common.primarygroup;
|
||||||
|
|
||||||
import me.lucko.luckperms.common.buffers.Cache;
|
import me.lucko.luckperms.common.buffers.Cache;
|
||||||
import me.lucko.luckperms.common.caching.handlers.StateListener;
|
|
||||||
import me.lucko.luckperms.common.model.User;
|
import me.lucko.luckperms.common.model.User;
|
||||||
import me.lucko.luckperms.common.node.factory.NodeFactory;
|
import me.lucko.luckperms.common.node.factory.NodeFactory;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract implementation of {@link StateListener} which caches all lookups.
|
* Abstract implementation of {@link PrimaryGroupHolder} which caches all lookups.
|
||||||
*/
|
*/
|
||||||
public abstract class CachedPrimaryGroupHolder extends StoredHolder implements StateListener {
|
public abstract class CachedPrimaryGroupHolder extends StoredHolder {
|
||||||
|
|
||||||
// cache lookups
|
// cache lookups
|
||||||
private final Cache<String> cache = new Cache<String>() {
|
private final Cache<String> cache = new Cache<String>() {
|
||||||
@ -48,20 +47,18 @@ public abstract class CachedPrimaryGroupHolder extends StoredHolder implements S
|
|||||||
|
|
||||||
public CachedPrimaryGroupHolder(User user) {
|
public CachedPrimaryGroupHolder(User user) {
|
||||||
super(user);
|
super(user);
|
||||||
user.getStateListeners().add(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract String calculateValue();
|
protected abstract String calculateValue();
|
||||||
|
|
||||||
|
public void invalidate() {
|
||||||
|
this.cache.invalidate();;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final String getValue() {
|
public final String getValue() {
|
||||||
String s = this.cache.get();
|
String s = this.cache.get();
|
||||||
return s != null ? s : getStoredValue().orElse(NodeFactory.DEFAULT_GROUP_NAME);
|
return s != null ? s : getStoredValue().orElse(NodeFactory.DEFAULT_GROUP_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStateChange() {
|
|
||||||
this.cache.invalidate();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -205,7 +205,7 @@ public abstract class AbstractConfigurateDao extends AbstractDao {
|
|||||||
} finally {
|
} finally {
|
||||||
user.getIoLock().unlock();
|
user.getIoLock().unlock();
|
||||||
}
|
}
|
||||||
user.getRefreshBuffer().requestDirectly();
|
user.reloadCachedData().join();
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,7 +261,7 @@ public abstract class AbstractConfigurateDao extends AbstractDao {
|
|||||||
} finally {
|
} finally {
|
||||||
group.getIoLock().unlock();
|
group.getIoLock().unlock();
|
||||||
}
|
}
|
||||||
group.getRefreshBuffer().requestDirectly();
|
group.reloadCachedData().join();
|
||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,7 +295,7 @@ public abstract class AbstractConfigurateDao extends AbstractDao {
|
|||||||
group.getIoLock().unlock();
|
group.getIoLock().unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
group.getRefreshBuffer().requestDirectly();
|
group.reloadCachedData().join();
|
||||||
return Optional.of(group);
|
return Optional.of(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,7 +286,7 @@ public class MongoDao extends AbstractDao {
|
|||||||
} finally {
|
} finally {
|
||||||
user.getIoLock().unlock();
|
user.getIoLock().unlock();
|
||||||
}
|
}
|
||||||
user.getRefreshBuffer().requestDirectly();
|
user.reloadCachedData().join();
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,7 +357,7 @@ public class MongoDao extends AbstractDao {
|
|||||||
} finally {
|
} finally {
|
||||||
group.getIoLock().unlock();
|
group.getIoLock().unlock();
|
||||||
}
|
}
|
||||||
group.getRefreshBuffer().requestDirectly();
|
group.reloadCachedData().join();
|
||||||
return group;
|
return group;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,7 +388,7 @@ public class MongoDao extends AbstractDao {
|
|||||||
group.getIoLock().unlock();
|
group.getIoLock().unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
group.getRefreshBuffer().requestDirectly();
|
group.reloadCachedData().join();
|
||||||
return Optional.of(group);
|
return Optional.of(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,7 +356,7 @@ public class SqlDao extends AbstractDao {
|
|||||||
} finally {
|
} finally {
|
||||||
user.getIoLock().unlock();
|
user.getIoLock().unlock();
|
||||||
}
|
}
|
||||||
user.getRefreshBuffer().requestDirectly();
|
user.reloadCachedData().join();
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -595,7 +595,7 @@ public class SqlDao extends AbstractDao {
|
|||||||
} finally {
|
} finally {
|
||||||
group.getIoLock().unlock();
|
group.getIoLock().unlock();
|
||||||
}
|
}
|
||||||
group.getRefreshBuffer().requestDirectly();
|
group.reloadCachedData().join();
|
||||||
return Optional.of(group);
|
return Optional.of(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ public class ExpireTemporaryTask implements Runnable {
|
|||||||
if (user.auditTemporaryPermissions()) {
|
if (user.auditTemporaryPermissions()) {
|
||||||
this.plugin.getStorage().saveUser(user);
|
this.plugin.getStorage().saveUser(user);
|
||||||
if (!groupChanges) {
|
if (!groupChanges) {
|
||||||
user.getRefreshBuffer().request();
|
user.reloadCachedData();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,11 +55,6 @@ public class NukkitConfigAdapter extends AbstractConfigurationAdapter implements
|
|||||||
this.configuration = new Config(this.file, Config.YAML);
|
this.configuration = new Config(this.file, Config.YAML);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean contains(String path) {
|
|
||||||
return this.configuration.exists(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getString(String path, String def) {
|
public String getString(String path, String def) {
|
||||||
return this.configuration.getString(path, def);
|
return this.configuration.getString(path, def);
|
||||||
|
@ -85,11 +85,6 @@ public class SpongeConfigAdapter extends AbstractConfigurationAdapter implements
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean contains(String path) {
|
|
||||||
return !resolvePath(path).isVirtual();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getString(String path, String def) {
|
public String getString(String path, String def) {
|
||||||
return resolvePath(path).getString(def);
|
return resolvePath(path).getString(def);
|
||||||
|
@ -37,6 +37,13 @@ public class SpongeGroup extends Group implements SpongePermissionHolder {
|
|||||||
this.spongeData = new GroupSubject(plugin, this);
|
this.spongeData = new GroupSubject(plugin, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void invalidateCache() {
|
||||||
|
super.invalidateCache();
|
||||||
|
|
||||||
|
this.spongeData.fireUpdateEvent();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GroupSubject sponge() {
|
public GroupSubject sponge() {
|
||||||
return this.spongeData;
|
return this.spongeData;
|
||||||
|
@ -48,6 +48,13 @@ public class SpongeUser extends User implements SpongePermissionHolder {
|
|||||||
this.spongeData = new UserSubject(plugin, this);
|
this.spongeData = new UserSubject(plugin, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void invalidateCache() {
|
||||||
|
super.invalidateCache();
|
||||||
|
|
||||||
|
this.spongeData.fireUpdateEvent();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserSubject sponge() {
|
public UserSubject sponge() {
|
||||||
return this.spongeData;
|
return this.spongeData;
|
||||||
|
@ -66,12 +66,11 @@ public abstract class HolderSubject<T extends PermissionHolder> implements LPSub
|
|||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.subjectData = new HolderSubjectData(plugin.getService(), NodeMapType.ENDURING, parent, this);
|
this.subjectData = new HolderSubjectData(plugin.getService(), NodeMapType.ENDURING, parent, this);
|
||||||
this.transientSubjectData = new HolderSubjectData(plugin.getService(), NodeMapType.TRANSIENT, parent, this);
|
this.transientSubjectData = new HolderSubjectData(plugin.getService(), NodeMapType.TRANSIENT, parent, this);
|
||||||
|
}
|
||||||
|
|
||||||
// fire update event
|
public void fireUpdateEvent() {
|
||||||
parent.getStateListeners().add(() -> {
|
this.plugin.getUpdateEventHandler().fireUpdateEvent(this.subjectData);
|
||||||
plugin.getUpdateEventHandler().fireUpdateEvent(this.subjectData);
|
this.plugin.getUpdateEventHandler().fireUpdateEvent(this.transientSubjectData);
|
||||||
plugin.getUpdateEventHandler().fireUpdateEvent(this.transientSubjectData);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public T getParent() {
|
public T getParent() {
|
||||||
|
@ -450,7 +450,7 @@ public class HolderSubjectData implements LPSubjectData {
|
|||||||
// don't bother saving to primary storage. just refresh
|
// don't bother saving to primary storage. just refresh
|
||||||
if (t.getType().isUser()) {
|
if (t.getType().isUser()) {
|
||||||
User user = ((User) t);
|
User user = ((User) t);
|
||||||
return user.getRefreshBuffer().request();
|
return user.reloadCachedData();
|
||||||
} else {
|
} else {
|
||||||
return this.service.getPlugin().getUpdateTaskBuffer().request();
|
return this.service.getPlugin().getUpdateTaskBuffer().request();
|
||||||
}
|
}
|
||||||
@ -465,7 +465,7 @@ public class HolderSubjectData implements LPSubjectData {
|
|||||||
fut.complete(null);
|
fut.complete(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
user.getRefreshBuffer().request().thenAccept(fut::complete);
|
user.reloadCachedData().thenAccept(fut::complete);
|
||||||
}, this.service.getPlugin().getBootstrap().getScheduler().async());
|
}, this.service.getPlugin().getBootstrap().getScheduler().async());
|
||||||
return fut;
|
return fut;
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user