diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/BukkitConfigAdapter.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/BukkitConfigAdapter.java index 21d6f428..499a86f4 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/BukkitConfigAdapter.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/BukkitConfigAdapter.java @@ -55,11 +55,6 @@ public class BukkitConfigAdapter extends AbstractConfigurationAdapter implements this.configuration = YamlConfiguration.loadConfiguration(this.file); } - @Override - public boolean contains(String path) { - return this.configuration.contains(path); - } - @Override public String getString(String path, String def) { return this.configuration.getString(path, def); diff --git a/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultPermissionHook.java b/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultPermissionHook.java index 23ab529a..6645fef1 100644 --- a/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultPermissionHook.java +++ b/bukkit/src/main/java/me/lucko/luckperms/bukkit/vault/VaultPermissionHook.java @@ -403,7 +403,7 @@ public class VaultPermissionHook extends AbstractVaultPermission { void holderSave(PermissionHolder holder) { if (holder.getType().isUser()) { 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()) { Group g = (Group) holder; diff --git a/bungee/src/main/java/me/lucko/luckperms/bungee/BungeeConfigAdapter.java b/bungee/src/main/java/me/lucko/luckperms/bungee/BungeeConfigAdapter.java index 47313d0c..c510beb6 100644 --- a/bungee/src/main/java/me/lucko/luckperms/bungee/BungeeConfigAdapter.java +++ b/bungee/src/main/java/me/lucko/luckperms/bungee/BungeeConfigAdapter.java @@ -61,11 +61,6 @@ public class BungeeConfigAdapter extends AbstractConfigurationAdapter implements } } - @Override - public boolean contains(String path) { - return this.configuration.contains(path); - } - @Override public String getString(String path, String def) { return this.configuration.getString(path, def); diff --git a/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiPermissionHolder.java b/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiPermissionHolder.java index 137f6c4f..00e18a6e 100644 --- a/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiPermissionHolder.java +++ b/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiPermissionHolder.java @@ -98,7 +98,7 @@ public class ApiPermissionHolder implements me.lucko.luckperms.api.PermissionHol @Nonnull @Override public CompletableFuture refreshCachedData() { - return this.handle.getRefreshBuffer().request(); + return this.handle.reloadCachedData(); } @Nonnull diff --git a/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiUser.java b/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiUser.java index 9300dbdd..ef4b50dc 100644 --- a/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiUser.java +++ b/common/src/main/java/me/lucko/luckperms/common/api/delegates/model/ApiUser.java @@ -99,7 +99,7 @@ public final class ApiUser extends ApiPermissionHolder implements me.lucko.luckp @Override @Deprecated public void refreshPermissions() { - this.handle.getRefreshBuffer().requestDirectly(); + this.handle.reloadCachedData().join(); } @Override diff --git a/common/src/main/java/me/lucko/luckperms/common/caching/AbstractCachedData.java b/common/src/main/java/me/lucko/luckperms/common/caching/AbstractCachedData.java index e9dcdfdd..c1d3b1c2 100644 --- a/common/src/main/java/me/lucko/luckperms/common/caching/AbstractCachedData.java +++ b/common/src/main/java/me/lucko/luckperms/common/caching/AbstractCachedData.java @@ -25,9 +25,9 @@ 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.Caffeine; -import com.github.benmanes.caffeine.cache.LoadingCache; import me.lucko.luckperms.api.ChatMetaType; 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.plugin.LuckPermsPlugin; -import java.util.HashSet; import java.util.Map; import java.util.Objects; import java.util.Set; @@ -51,6 +50,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import javax.annotation.Nonnull; +import javax.annotation.Nullable; /** * Abstract implementation of {@link CachedData}. @@ -65,16 +65,16 @@ public abstract class AbstractCachedData implements CachedData { /** * The cache used for {@link PermissionCache} instances. */ - private final LoadingCache permission = Caffeine.newBuilder() + private final AsyncLoadingCache permission = Caffeine.newBuilder() .expireAfterAccess(2, TimeUnit.MINUTES) - .build(new PermissionCacheLoader()); + .buildAsync(new PermissionCacheLoader()); /** * The cache used for {@link MetaCache} instances. */ - private final LoadingCache meta = Caffeine.newBuilder() + private final AsyncLoadingCache meta = Caffeine.newBuilder() .expireAfterAccess(2, TimeUnit.MINUTES) - .build(new MetaCacheLoader()); + .buildAsync(new MetaCacheLoader()); public AbstractCachedData(LuckPermsPlugin plugin) { this.plugin = plugin; @@ -190,7 +190,7 @@ public abstract class AbstractCachedData implements CachedData { Objects.requireNonNull(contexts, "contexts"); //noinspection ConstantConditions - return this.permission.get(contexts); + return this.permission.get(contexts).join(); } @Nonnull @@ -199,7 +199,7 @@ public abstract class AbstractCachedData implements CachedData { Objects.requireNonNull(contexts, "contexts"); //noinspection ConstantConditions - return this.meta.get(contexts); + return this.meta.get(contexts).join(); } @Nonnull @@ -233,13 +233,13 @@ public abstract class AbstractCachedData implements CachedData { @Override public void recalculatePermissions(@Nonnull Contexts contexts) { Objects.requireNonNull(contexts, "contexts"); - this.permission.refresh(contexts); + this.permission.synchronous().refresh(contexts); } @Override public void recalculateMeta(@Nonnull MetaContexts contexts) { Objects.requireNonNull(contexts, "contexts"); - this.meta.refresh(contexts); + this.meta.synchronous().refresh(contexts); } @Override @@ -254,13 +254,19 @@ public abstract class AbstractCachedData implements CachedData { Objects.requireNonNull(contexts, "contexts"); // get the previous value - to use when recalculating - PermissionCache previous = this.permission.getIfPresent(contexts); + CompletableFuture previous = this.permission.getIfPresent(contexts); - // invalidate the entry - this.permission.invalidate(contexts); + // invalidate any previous setting + this.permission.synchronous().invalidate(contexts); - // repopulate the cache - return CompletableFuture.supplyAsync(() -> this.permission.get(contexts, c -> calculatePermissions(c, previous))); + // if the previous value is already calculated, use it when recalculating. + 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 @@ -269,13 +275,19 @@ public abstract class AbstractCachedData implements CachedData { Objects.requireNonNull(contexts, "contexts"); // get the previous value - to use when recalculating - MetaCache previous = this.meta.getIfPresent(contexts); + CompletableFuture previous = this.meta.getIfPresent(contexts); - // invalidate the entry - this.meta.invalidate(contexts); + // invalidate any previous setting + this.meta.synchronous().invalidate(contexts); - // repopulate the cache - return CompletableFuture.supplyAsync(() -> this.meta.get(contexts, c -> calculateMeta(c, previous))); + // if the previous value is already calculated, use it when recalculating. + 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 @@ -287,30 +299,34 @@ public abstract class AbstractCachedData implements CachedData { @Override public void recalculatePermissions() { - Set keys = this.permission.asMap().keySet(); + Set keys = this.permission.synchronous().asMap().keySet(); keys.forEach(this::recalculatePermissions); } @Override public void recalculateMeta() { - Set keys = this.meta.asMap().keySet(); + Set keys = this.meta.synchronous().asMap().keySet(); keys.forEach(this::recalculateMeta); } @Nonnull @Override public CompletableFuture reloadPermissions() { - Set keys = new HashSet<>(this.permission.asMap().keySet()); + Set keys = this.permission.synchronous().asMap().keySet(); return CompletableFuture.allOf(keys.stream().map(this::reloadPermissions).toArray(CompletableFuture[]::new)); } @Nonnull @Override public CompletableFuture reloadMeta() { - Set keys = new HashSet<>(this.meta.asMap().keySet()); + Set keys = this.meta.synchronous().asMap().keySet(); return CompletableFuture.allOf(keys.stream().map(this::reloadMeta).toArray(CompletableFuture[]::new)); } + public CompletableFuture reloadAll() { + return CompletableFuture.allOf(reloadPermissions(), reloadMeta()); + } + @Override public void preCalculate(@Nonnull Contexts contexts) { Objects.requireNonNull(contexts, "contexts"); @@ -324,34 +340,45 @@ public abstract class AbstractCachedData implements CachedData { @Override public void invalidatePermissions(@Nonnull Contexts contexts) { Objects.requireNonNull(contexts, "contexts"); - this.permission.invalidate(contexts); + this.permission.synchronous().invalidate(contexts); } @Override public void invalidateMeta(@Nonnull MetaContexts contexts) { Objects.requireNonNull(contexts, "contexts"); - this.meta.invalidate(contexts); + this.meta.synchronous().invalidate(contexts); } @Override public void invalidateMeta(@Nonnull Contexts contexts) { Objects.requireNonNull(contexts, "contexts"); - this.meta.invalidate(getDefaultMetaContexts(contexts)); + this.meta.synchronous().invalidate(getDefaultMetaContexts(contexts)); } @Override public void invalidatePermissionCalculators() { - this.permission.asMap().values().forEach(PermissionCache::invalidateCache); + this.permission.synchronous().asMap().values().forEach(PermissionCache::invalidateCache); } public void invalidateCaches() { - this.permission.invalidateAll(); - this.meta.invalidateAll(); + this.permission.synchronous().invalidateAll(); + this.meta.synchronous().invalidateAll(); } public void doCacheCleanup() { - this.permission.cleanUp(); - this.meta.cleanUp(); + this.permission.synchronous().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 getIfReady(@Nullable CompletableFuture future) { + return isReady(future) ? future.join() : null; } private final class PermissionCacheLoader implements CacheLoader { diff --git a/common/src/main/java/me/lucko/luckperms/common/command/utils/StorageAssistant.java b/common/src/main/java/me/lucko/luckperms/common/command/utils/StorageAssistant.java index 7f3c2c70..105f4de7 100644 --- a/common/src/main/java/me/lucko/luckperms/common/command/utils/StorageAssistant.java +++ b/common/src/main/java/me/lucko/luckperms/common/command/utils/StorageAssistant.java @@ -108,7 +108,7 @@ public final class StorageAssistant { return; } - user.getRefreshBuffer().requestDirectly(); + user.reloadCachedData().join(); Optional messagingService = plugin.getMessagingService(); if (messagingService.isPresent() && plugin.getConfiguration().get(ConfigKeys.AUTO_PUSH_UPDATES)) { diff --git a/common/src/main/java/me/lucko/luckperms/common/config/adapter/ConfigurationAdapter.java b/common/src/main/java/me/lucko/luckperms/common/config/adapter/ConfigurationAdapter.java index 24664cfa..8a23cf04 100644 --- a/common/src/main/java/me/lucko/luckperms/common/config/adapter/ConfigurationAdapter.java +++ b/common/src/main/java/me/lucko/luckperms/common/config/adapter/ConfigurationAdapter.java @@ -36,8 +36,6 @@ public interface ConfigurationAdapter { void reload(); - boolean contains(String path); - String getString(String path, String def); int getInt(String path, int def); diff --git a/common/src/main/java/me/lucko/luckperms/common/model/Group.java b/common/src/main/java/me/lucko/luckperms/common/model/Group.java index 4eed7d47..efc7e7ba 100644 --- a/common/src/main/java/me/lucko/luckperms/common/model/Group.java +++ b/common/src/main/java/me/lucko/luckperms/common/model/Group.java @@ -29,7 +29,6 @@ import me.lucko.luckperms.api.Node; import me.lucko.luckperms.api.context.ContextSet; import me.lucko.luckperms.api.nodetype.types.DisplayNameType; 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.caching.GroupCachedData; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; @@ -61,34 +60,66 @@ public class Group extends PermissionHolder implements Identifiable { */ private final GroupCachedData cachedData; - /** - * The group's cached data refresh buffer - */ - private final GroupRefreshBuffer refreshBuffer; - public Group(String name, LuckPermsPlugin plugin) { - super(name, plugin); + super(plugin); this.name = name.toLowerCase(); - this.refreshBuffer = new GroupRefreshBuffer(plugin, this); this.cachedData = new GroupCachedData(this); getPlugin().getEventFactory().handleGroupCacheLoad(this, this.cachedData); - - // invalidate our caches when data is updated - getStateListeners().add(this.refreshBuffer::request); } @Override protected void invalidateCache() { + super.invalidateCache(); + + // invalidate our caches this.weightCache.invalidate(); this.displayNameCache.invalidate(); - super.invalidateCache(); } + // name getters public String getName() { return this.name; } + @Override + public String getObjectName() { + return this.name; + } + + @Override + public String getId() { + return this.name; + } + + @Override + public String getFriendlyName() { + Optional dn = getDisplayName(); + return dn.map(s -> this.name + " (" + s + ")").orElse(this.name); + } + + public Optional getDisplayName() { + return this.displayNameCache.get(); + } + + /** + * Gets a display name value exactly matching a specific context. + * + *

Note that the behaviour of {@link #getDisplayName()} is not the same as this.

+ * + * @param contextSet the contexts to lookup in + * @return the display name + */ + public Optional getDisplayName(ContextSet contextSet) { + for (Node n : getData(NodeMapType.ENDURING).immutable().get(contextSet.makeImmutable())) { + Optional displayName = n.getTypeData(DisplayNameType.KEY); + if (displayName.isPresent()) { + return Optional.of(displayName.get().getDisplayName()); + } + } + return Optional.empty(); + } + public ApiGroup getApiDelegate() { return this.apiDelegate; } @@ -98,36 +129,6 @@ public class Group extends PermissionHolder implements Identifiable { return this.cachedData; } - @Override - public BufferedRequest getRefreshBuffer() { - return this.refreshBuffer; - } - - @Override - public String getId() { - return this.name; - } - - public Optional getDisplayName() { - return this.displayNameCache.get(); - } - - public Optional getDisplayName(ContextSet contextSet) { - for (Node n : getData(NodeMapType.ENDURING).immutable().get(contextSet.makeImmutable())) { - Optional displayName = n.getTypeData(DisplayNameType.KEY); - if (displayName.isPresent()) { - return Optional.of(displayName.get().getDisplayName()); - } - } - return Optional.empty(); - } - - @Override - public String getFriendlyName() { - Optional dn = getDisplayName(); - return dn.map(s -> this.name + " (" + s + ")").orElse(this.name); - } - @Override public OptionalInt getWeight() { return this.weightCache.get(); @@ -138,11 +139,10 @@ public class Group extends PermissionHolder implements Identifiable { return HolderType.GROUP; } - private CompletableFuture reloadCachedData() { - return CompletableFuture.allOf( - this.cachedData.reloadPermissions(), - this.cachedData.reloadMeta() - ).thenAccept(n -> getPlugin().getEventFactory().handleGroupDataRecalculate(this, this.cachedData)); + @Override + public CompletableFuture reloadCachedData() { + return this.cachedData.reloadAll() + .thenAccept(n -> getPlugin().getEventFactory().handleGroupDataRecalculate(this, this.cachedData)); } @Override @@ -163,18 +163,4 @@ public class Group extends PermissionHolder implements Identifiable { return "Group(name=" + this.name + ")"; } - private static final class GroupRefreshBuffer extends BufferedRequest { - 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(); - } - } - } diff --git a/common/src/main/java/me/lucko/luckperms/common/model/PermissionHolder.java b/common/src/main/java/me/lucko/luckperms/common/model/PermissionHolder.java index 9f83e8fe..bd7bd379 100644 --- a/common/src/main/java/me/lucko/luckperms/common/model/PermissionHolder.java +++ b/common/src/main/java/me/lucko/luckperms/common/model/PermissionHolder.java @@ -40,9 +40,7 @@ import me.lucko.luckperms.api.StandardNodeEquality; import me.lucko.luckperms.api.Tristate; import me.lucko.luckperms.api.context.ContextSet; 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.handlers.StateListener; import me.lucko.luckperms.common.caching.type.MetaAccumulator; import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.inheritance.InheritanceComparator; @@ -67,7 +65,7 @@ import java.util.OptionalInt; import java.util.Set; import java.util.SortedSet; 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.ReentrantLock; import java.util.function.Predicate; @@ -95,18 +93,6 @@ import java.util.function.Predicate; */ public abstract class PermissionHolder { - /** - * The name of this object. - * - *

Used as a base for identifying permission holding objects. Also acts - * as a method for preventing circular inheritance issues.

- * - * @see User#getUuid() - * @see Group#getName() - * @see #getObjectName() - */ - private final String objectName; - /** * Reference to the main plugin instance * @see #getPlugin() @@ -146,18 +132,15 @@ public abstract class PermissionHolder { private final Comparator 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 stateListeners = ConcurrentHashMap.newKeySet(); - - protected PermissionHolder(String objectName, LuckPermsPlugin plugin) { - this.objectName = objectName; + protected PermissionHolder(LuckPermsPlugin plugin) { this.plugin = plugin; } - public String getObjectName() { - return this.objectName; - } + // getters public LuckPermsPlugin getPlugin() { return this.plugin; @@ -167,52 +150,6 @@ public abstract class PermissionHolder { return this.ioLock; } - public Set 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 getRefreshBuffer(); - - /** - * Returns the type of this PermissionHolder. - * - * @return this holders type - */ - public abstract HolderType getType(); - public Comparator getInheritanceComparator() { return this.inheritanceComparator; } @@ -236,6 +173,51 @@ public abstract class PermissionHolder { return this.transientNodes; } + /** + * Gets the unique name of this holder object. + * + *

Used as a base for identifying permission holding objects. Also acts + * as a method for preventing circular inheritance issues.

+ * + * @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 reloadCachedData(); + + protected void invalidateCache() { + this.enduringNodes.invalidate(); + this.transientNodes.invalidate(); + + reloadCachedData(); + } + public void setNodes(NodeMapType type, Set set) { getData(type).setContent(set); invalidateCache(); diff --git a/common/src/main/java/me/lucko/luckperms/common/model/User.java b/common/src/main/java/me/lucko/luckperms/common/model/User.java index d99bc1a8..9f6d9e2e 100644 --- a/common/src/main/java/me/lucko/luckperms/common/model/User.java +++ b/common/src/main/java/me/lucko/luckperms/common/model/User.java @@ -26,16 +26,18 @@ package me.lucko.luckperms.common.model; 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.config.ConfigKeys; import me.lucko.luckperms.common.plugin.LuckPermsPlugin; +import me.lucko.luckperms.common.primarygroup.CachedPrimaryGroupHolder; import me.lucko.luckperms.common.primarygroup.PrimaryGroupHolder; import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; +import javax.annotation.Nullable; + public class User extends PermissionHolder implements Identifiable { /** @@ -46,6 +48,7 @@ public class User extends PermissionHolder implements Identifiable getName() { + return Optional.ofNullable(this.name); } @Override - public UserCachedData getCachedData() { - return this.cachedData; - } - - @Override - public BufferedRequest getRefreshBuffer() { - return this.refreshBuffer; + public String getObjectName() { + return this.uuid.toString(); } @Override @@ -99,8 +104,18 @@ public class User extends PermissionHolder implements Identifiable getName() { - return Optional.ofNullable(this.name); + @Override + 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 reloadCachedData() { - return CompletableFuture.allOf( - this.cachedData.reloadPermissions(), - this.cachedData.reloadMeta() - ).thenAccept(n -> getPlugin().getEventFactory().handleUserDataRecalculate(this, this.cachedData)); + return this.cachedData.reloadAll() + .thenAccept(n -> getPlugin().getEventFactory().handleUserDataRecalculate(this, this.cachedData)); } /** @@ -197,13 +206,6 @@ public class User extends PermissionHolder implements Identifiable { - 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(); - } - } - } diff --git a/common/src/main/java/me/lucko/luckperms/common/primarygroup/CachedPrimaryGroupHolder.java b/common/src/main/java/me/lucko/luckperms/common/primarygroup/CachedPrimaryGroupHolder.java index a718754a..84498b64 100644 --- a/common/src/main/java/me/lucko/luckperms/common/primarygroup/CachedPrimaryGroupHolder.java +++ b/common/src/main/java/me/lucko/luckperms/common/primarygroup/CachedPrimaryGroupHolder.java @@ -26,16 +26,15 @@ package me.lucko.luckperms.common.primarygroup; 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.node.factory.NodeFactory; 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 private final Cache cache = new Cache() { @@ -48,20 +47,18 @@ public abstract class CachedPrimaryGroupHolder extends StoredHolder implements S public CachedPrimaryGroupHolder(User user) { super(user); - user.getStateListeners().add(this); } protected abstract String calculateValue(); + public void invalidate() { + this.cache.invalidate();; + } + @Override public final String getValue() { String s = this.cache.get(); return s != null ? s : getStoredValue().orElse(NodeFactory.DEFAULT_GROUP_NAME); } - @Override - public void onStateChange() { - this.cache.invalidate(); - } - } diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/AbstractConfigurateDao.java b/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/AbstractConfigurateDao.java index efe9a30d..f302bbbb 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/AbstractConfigurateDao.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/dao/file/AbstractConfigurateDao.java @@ -205,7 +205,7 @@ public abstract class AbstractConfigurateDao extends AbstractDao { } finally { user.getIoLock().unlock(); } - user.getRefreshBuffer().requestDirectly(); + user.reloadCachedData().join(); return user; } @@ -261,7 +261,7 @@ public abstract class AbstractConfigurateDao extends AbstractDao { } finally { group.getIoLock().unlock(); } - group.getRefreshBuffer().requestDirectly(); + group.reloadCachedData().join(); return group; } @@ -295,7 +295,7 @@ public abstract class AbstractConfigurateDao extends AbstractDao { group.getIoLock().unlock(); } } - group.getRefreshBuffer().requestDirectly(); + group.reloadCachedData().join(); return Optional.of(group); } diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/dao/mongodb/MongoDao.java b/common/src/main/java/me/lucko/luckperms/common/storage/dao/mongodb/MongoDao.java index bc1812da..f391c599 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/dao/mongodb/MongoDao.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/dao/mongodb/MongoDao.java @@ -286,7 +286,7 @@ public class MongoDao extends AbstractDao { } finally { user.getIoLock().unlock(); } - user.getRefreshBuffer().requestDirectly(); + user.reloadCachedData().join(); return user; } @@ -357,7 +357,7 @@ public class MongoDao extends AbstractDao { } finally { group.getIoLock().unlock(); } - group.getRefreshBuffer().requestDirectly(); + group.reloadCachedData().join(); return group; } @@ -388,7 +388,7 @@ public class MongoDao extends AbstractDao { group.getIoLock().unlock(); } } - group.getRefreshBuffer().requestDirectly(); + group.reloadCachedData().join(); return Optional.of(group); } diff --git a/common/src/main/java/me/lucko/luckperms/common/storage/dao/sql/SqlDao.java b/common/src/main/java/me/lucko/luckperms/common/storage/dao/sql/SqlDao.java index 83f21e7d..732fc352 100644 --- a/common/src/main/java/me/lucko/luckperms/common/storage/dao/sql/SqlDao.java +++ b/common/src/main/java/me/lucko/luckperms/common/storage/dao/sql/SqlDao.java @@ -356,7 +356,7 @@ public class SqlDao extends AbstractDao { } finally { user.getIoLock().unlock(); } - user.getRefreshBuffer().requestDirectly(); + user.reloadCachedData().join(); return user; } @@ -595,7 +595,7 @@ public class SqlDao extends AbstractDao { } finally { group.getIoLock().unlock(); } - group.getRefreshBuffer().requestDirectly(); + group.reloadCachedData().join(); return Optional.of(group); } diff --git a/common/src/main/java/me/lucko/luckperms/common/tasks/ExpireTemporaryTask.java b/common/src/main/java/me/lucko/luckperms/common/tasks/ExpireTemporaryTask.java index 85ebf797..8a1a60b5 100644 --- a/common/src/main/java/me/lucko/luckperms/common/tasks/ExpireTemporaryTask.java +++ b/common/src/main/java/me/lucko/luckperms/common/tasks/ExpireTemporaryTask.java @@ -57,7 +57,7 @@ public class ExpireTemporaryTask implements Runnable { if (user.auditTemporaryPermissions()) { this.plugin.getStorage().saveUser(user); if (!groupChanges) { - user.getRefreshBuffer().request(); + user.reloadCachedData(); } } } diff --git a/nukkit/src/main/java/me/lucko/luckperms/nukkit/NukkitConfigAdapter.java b/nukkit/src/main/java/me/lucko/luckperms/nukkit/NukkitConfigAdapter.java index 1b815860..73e09920 100644 --- a/nukkit/src/main/java/me/lucko/luckperms/nukkit/NukkitConfigAdapter.java +++ b/nukkit/src/main/java/me/lucko/luckperms/nukkit/NukkitConfigAdapter.java @@ -55,11 +55,6 @@ public class NukkitConfigAdapter extends AbstractConfigurationAdapter implements this.configuration = new Config(this.file, Config.YAML); } - @Override - public boolean contains(String path) { - return this.configuration.exists(path); - } - @Override public String getString(String path, String def) { return this.configuration.getString(path, def); diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeConfigAdapter.java b/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeConfigAdapter.java index 59a8f1eb..b7780dd3 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeConfigAdapter.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/SpongeConfigAdapter.java @@ -85,11 +85,6 @@ public class SpongeConfigAdapter extends AbstractConfigurationAdapter implements return node; } - @Override - public boolean contains(String path) { - return !resolvePath(path).isVirtual(); - } - @Override public String getString(String path, String def) { return resolvePath(path).getString(def); diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/model/SpongeGroup.java b/sponge/src/main/java/me/lucko/luckperms/sponge/model/SpongeGroup.java index 0659030d..f433bb21 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/model/SpongeGroup.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/model/SpongeGroup.java @@ -37,6 +37,13 @@ public class SpongeGroup extends Group implements SpongePermissionHolder { this.spongeData = new GroupSubject(plugin, this); } + @Override + protected void invalidateCache() { + super.invalidateCache(); + + this.spongeData.fireUpdateEvent(); + } + @Override public GroupSubject sponge() { return this.spongeData; diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/model/SpongeUser.java b/sponge/src/main/java/me/lucko/luckperms/sponge/model/SpongeUser.java index d0c58a9b..7a5098b1 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/model/SpongeUser.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/model/SpongeUser.java @@ -48,6 +48,13 @@ public class SpongeUser extends User implements SpongePermissionHolder { this.spongeData = new UserSubject(plugin, this); } + @Override + protected void invalidateCache() { + super.invalidateCache(); + + this.spongeData.fireUpdateEvent(); + } + @Override public UserSubject sponge() { return this.spongeData; diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/internal/HolderSubject.java b/sponge/src/main/java/me/lucko/luckperms/sponge/service/internal/HolderSubject.java index 42f4be6b..d247e4c1 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/service/internal/HolderSubject.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/service/internal/HolderSubject.java @@ -66,12 +66,11 @@ public abstract class HolderSubject implements LPSub this.plugin = plugin; this.subjectData = new HolderSubjectData(plugin.getService(), NodeMapType.ENDURING, parent, this); this.transientSubjectData = new HolderSubjectData(plugin.getService(), NodeMapType.TRANSIENT, parent, this); + } - // fire update event - parent.getStateListeners().add(() -> { - plugin.getUpdateEventHandler().fireUpdateEvent(this.subjectData); - plugin.getUpdateEventHandler().fireUpdateEvent(this.transientSubjectData); - }); + public void fireUpdateEvent() { + this.plugin.getUpdateEventHandler().fireUpdateEvent(this.subjectData); + this.plugin.getUpdateEventHandler().fireUpdateEvent(this.transientSubjectData); } public T getParent() { diff --git a/sponge/src/main/java/me/lucko/luckperms/sponge/service/internal/HolderSubjectData.java b/sponge/src/main/java/me/lucko/luckperms/sponge/service/internal/HolderSubjectData.java index 22b65d95..1b4473bf 100644 --- a/sponge/src/main/java/me/lucko/luckperms/sponge/service/internal/HolderSubjectData.java +++ b/sponge/src/main/java/me/lucko/luckperms/sponge/service/internal/HolderSubjectData.java @@ -450,7 +450,7 @@ public class HolderSubjectData implements LPSubjectData { // don't bother saving to primary storage. just refresh if (t.getType().isUser()) { User user = ((User) t); - return user.getRefreshBuffer().request(); + return user.reloadCachedData(); } else { return this.service.getPlugin().getUpdateTaskBuffer().request(); } @@ -465,7 +465,7 @@ public class HolderSubjectData implements LPSubjectData { fut.complete(null); } - user.getRefreshBuffer().request().thenAccept(fut::complete); + user.reloadCachedData().thenAccept(fut::complete); }, this.service.getPlugin().getBootstrap().getScheduler().async()); return fut; } else {