Fix bad caching logic resulting in super high CPU usage
This commit is contained in:
parent
d8a7d8de4a
commit
10c0efaa5d
@ -178,9 +178,7 @@ public class LPPermissionAttachment extends PermissionAttachment {
|
||||
|
||||
// set the transient node
|
||||
User user = this.permissible.getUser();
|
||||
if (user.setTransientPermission(transientNode).asBoolean()) {
|
||||
user.reloadCachedData();
|
||||
}
|
||||
user.setTransientPermission(transientNode);
|
||||
}
|
||||
|
||||
private void unsetPermissionInternal(String name) {
|
||||
@ -190,17 +188,13 @@ public class LPPermissionAttachment extends PermissionAttachment {
|
||||
|
||||
// remove transient permissions from the holder which were added by this attachment & equal the permission
|
||||
User user = this.permissible.getUser();
|
||||
if (user.removeIfTransient(n -> n instanceof ImmutableTransientNode && ((ImmutableTransientNode) n).getOwner() == this && n.getPermission().equals(name))) {
|
||||
user.reloadCachedData();
|
||||
}
|
||||
user.removeIfTransient(n -> n instanceof ImmutableTransientNode && ((ImmutableTransientNode) n).getOwner() == this && n.getPermission().equals(name));
|
||||
}
|
||||
|
||||
private void clearInternal() {
|
||||
// remove all transient permissions added by this attachment
|
||||
User user = this.permissible.getUser();
|
||||
if (user.removeIfTransient(n -> n instanceof ImmutableTransientNode && ((ImmutableTransientNode) n).getOwner() == this)) {
|
||||
user.reloadCachedData();
|
||||
}
|
||||
user.removeIfTransient(n -> n instanceof ImmutableTransientNode && ((ImmutableTransientNode) n).getOwner() == this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -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.reloadCachedData(), this.plugin.getBootstrap().getScheduler().async());
|
||||
this.plugin.getStorage().saveUser(u);
|
||||
}
|
||||
if (holder.getType().isGroup()) {
|
||||
Group g = (Group) holder;
|
||||
|
@ -99,7 +99,7 @@ public class ApiPermissionHolder implements me.lucko.luckperms.api.PermissionHol
|
||||
@Nonnull
|
||||
@Override
|
||||
public CompletableFuture<Void> refreshCachedData() {
|
||||
return this.handle.reloadCachedData();
|
||||
return this.handle.getCachedData().reloadAll();
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
|
@ -99,13 +99,13 @@ public final class ApiUser extends ApiPermissionHolder implements me.lucko.luckp
|
||||
@Override
|
||||
@Deprecated
|
||||
public void refreshPermissions() {
|
||||
this.handle.reloadCachedData().join();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public void setupDataCache() {
|
||||
this.handle.preCalculateData();
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -108,8 +108,6 @@ public final class StorageAssistant {
|
||||
return;
|
||||
}
|
||||
|
||||
user.reloadCachedData().join();
|
||||
|
||||
Optional<InternalMessagingService> messagingService = plugin.getMessagingService();
|
||||
if (messagingService.isPresent() && plugin.getConfiguration().get(ConfigKeys.AUTO_PUSH_UPDATES)) {
|
||||
messagingService.get().pushUserUpdate(user);
|
||||
|
@ -117,11 +117,6 @@ public final class EventFactory {
|
||||
fireEventAsync(event);
|
||||
}
|
||||
|
||||
public void handleGroupDataRecalculate(Group group, GroupData data) {
|
||||
EventGroupDataRecalculate event = new EventGroupDataRecalculate(group.getApiDelegate(), data);
|
||||
fireEventAsync(event);
|
||||
}
|
||||
|
||||
public void handleGroupDelete(Group group, DeletionCause cause) {
|
||||
EventGroupDelete event = new EventGroupDelete(group.getName(), ImmutableSet.copyOf(group.enduringData().immutable().values()), cause);
|
||||
fireEventAsync(event);
|
||||
@ -249,9 +244,16 @@ public final class EventFactory {
|
||||
fireEventAsync(event);
|
||||
}
|
||||
|
||||
public void handleUserDataRecalculate(User user, UserData data) {
|
||||
EventUserDataRecalculate event = new EventUserDataRecalculate(new ApiUser(user), data);
|
||||
public void handleDataRecalculate(PermissionHolder holder) {
|
||||
if (holder.getType().isUser()) {
|
||||
User user = (User) holder;
|
||||
EventUserDataRecalculate event = new EventUserDataRecalculate(user.getApiDelegate(), user.getCachedData());
|
||||
fireEventAsync(event);
|
||||
} else {
|
||||
Group group = (Group) holder;
|
||||
EventGroupDataRecalculate event = new EventGroupDataRecalculate(group.getApiDelegate(), group.getCachedData());
|
||||
fireEventAsync(event);
|
||||
}
|
||||
}
|
||||
|
||||
public void handleUserFirstLogin(UUID uuid, String username) {
|
||||
|
@ -89,9 +89,6 @@ public abstract class AbstractConnectionListener implements ConnectionListener {
|
||||
if (save) {
|
||||
this.plugin.getStorage().saveUser(user).join();
|
||||
}
|
||||
|
||||
// Does some minimum pre-calculations to (maybe) speed things up later.
|
||||
user.preCalculateData();
|
||||
}
|
||||
|
||||
final long time = System.currentTimeMillis() - startTime;
|
||||
|
@ -35,7 +35,6 @@ import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class Group extends PermissionHolder implements Identifiable<String> {
|
||||
private final ApiGroup apiDelegate = new ApiGroup(this);
|
||||
@ -139,12 +138,6 @@ public class Group extends PermissionHolder implements Identifiable<String> {
|
||||
return HolderType.GROUP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> reloadCachedData() {
|
||||
return this.cachedData.reloadAll()
|
||||
.thenAccept(n -> getPlugin().getEventFactory().handleGroupDataRecalculate(this, this.cachedData));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) return true;
|
||||
|
@ -63,7 +63,6 @@ import java.util.OptionalInt;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.function.Predicate;
|
||||
@ -203,17 +202,18 @@ public abstract class PermissionHolder {
|
||||
public abstract HolderType getType();
|
||||
|
||||
/**
|
||||
* Reloads the holder's cached data.
|
||||
*
|
||||
* @return a future encapsulating the result
|
||||
* Invalidates the holder's cached data.
|
||||
*/
|
||||
public abstract CompletableFuture<Void> reloadCachedData();
|
||||
public void invalidateCachedData() {
|
||||
getCachedData().invalidateCaches();
|
||||
}
|
||||
|
||||
protected void invalidateCache() {
|
||||
this.enduringNodes.invalidate();
|
||||
this.transientNodes.invalidate();
|
||||
|
||||
reloadCachedData();
|
||||
invalidateCachedData();
|
||||
getPlugin().getEventFactory().handleDataRecalculate(this);
|
||||
}
|
||||
|
||||
public void setNodes(NodeMapType type, Set<? extends Node> set) {
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
package me.lucko.luckperms.common.model;
|
||||
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.common.api.delegates.model.ApiUser;
|
||||
import me.lucko.luckperms.common.caching.UserCachedData;
|
||||
import me.lucko.luckperms.common.config.ConfigKeys;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
@ -34,11 +34,11 @@ 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<UserIdentifier> {
|
||||
private final ApiUser apiDelegate = new ApiUser(this);
|
||||
|
||||
/**
|
||||
* The users Mojang UUID
|
||||
@ -109,6 +109,10 @@ public class User extends PermissionHolder implements Identifiable<UserIdentifie
|
||||
return this.name != null ? this.name : this.uuid.toString();
|
||||
}
|
||||
|
||||
public ApiUser getApiDelegate() {
|
||||
return this.apiDelegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserCachedData getCachedData() {
|
||||
return this.cachedData;
|
||||
@ -172,26 +176,6 @@ public class User extends PermissionHolder implements Identifiable<UserIdentifie
|
||||
return HolderType.USER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the UserData cache
|
||||
* Blocking call.
|
||||
*/
|
||||
public void preCalculateData() {
|
||||
// first try to refresh any existing permissions
|
||||
reloadCachedData().join();
|
||||
|
||||
// pre-calc the allowall & global contexts
|
||||
// since contexts change so frequently, it's not worth trying to calculate any more than this.
|
||||
this.cachedData.preCalculate(Contexts.allowAll());
|
||||
this.cachedData.preCalculate(Contexts.global());
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> reloadCachedData() {
|
||||
return this.cachedData.reloadAll()
|
||||
.thenAccept(n -> getPlugin().getEventFactory().handleUserDataRecalculate(this, this.cachedData));
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear all of the users permission nodes
|
||||
*/
|
||||
|
@ -205,7 +205,6 @@ public abstract class AbstractConfigurateDao extends AbstractDao {
|
||||
} finally {
|
||||
user.getIoLock().unlock();
|
||||
}
|
||||
user.reloadCachedData().join();
|
||||
return user;
|
||||
}
|
||||
|
||||
@ -261,7 +260,6 @@ public abstract class AbstractConfigurateDao extends AbstractDao {
|
||||
} finally {
|
||||
group.getIoLock().unlock();
|
||||
}
|
||||
group.reloadCachedData().join();
|
||||
return group;
|
||||
}
|
||||
|
||||
@ -295,7 +293,6 @@ public abstract class AbstractConfigurateDao extends AbstractDao {
|
||||
group.getIoLock().unlock();
|
||||
}
|
||||
}
|
||||
group.reloadCachedData().join();
|
||||
return Optional.of(group);
|
||||
}
|
||||
|
||||
|
@ -287,7 +287,6 @@ public class MongoDao extends AbstractDao {
|
||||
} finally {
|
||||
user.getIoLock().unlock();
|
||||
}
|
||||
user.reloadCachedData().join();
|
||||
return user;
|
||||
}
|
||||
|
||||
@ -358,7 +357,6 @@ public class MongoDao extends AbstractDao {
|
||||
} finally {
|
||||
group.getIoLock().unlock();
|
||||
}
|
||||
group.reloadCachedData().join();
|
||||
return group;
|
||||
}
|
||||
|
||||
@ -389,7 +387,6 @@ public class MongoDao extends AbstractDao {
|
||||
group.getIoLock().unlock();
|
||||
}
|
||||
}
|
||||
group.reloadCachedData().join();
|
||||
return Optional.of(group);
|
||||
}
|
||||
|
||||
|
@ -357,7 +357,6 @@ public class SqlDao extends AbstractDao {
|
||||
} finally {
|
||||
user.getIoLock().unlock();
|
||||
}
|
||||
user.reloadCachedData().join();
|
||||
return user;
|
||||
}
|
||||
|
||||
@ -596,7 +595,6 @@ public class SqlDao extends AbstractDao {
|
||||
} finally {
|
||||
group.getIoLock().unlock();
|
||||
}
|
||||
group.reloadCachedData().join();
|
||||
return Optional.of(group);
|
||||
}
|
||||
|
||||
|
@ -56,9 +56,6 @@ public class ExpireTemporaryTask implements Runnable {
|
||||
}
|
||||
if (user.auditTemporaryPermissions()) {
|
||||
this.plugin.getStorage().saveUser(user);
|
||||
if (!groupChanges) {
|
||||
user.reloadCachedData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -179,9 +179,7 @@ public class LPPermissionAttachment extends PermissionAttachment {
|
||||
|
||||
// set the transient node
|
||||
User user = this.permissible.getUser();
|
||||
if (user.setTransientPermission(transientNode).asBoolean()) {
|
||||
user.reloadCachedData();
|
||||
}
|
||||
user.setTransientPermission(transientNode).asBoolean();
|
||||
}
|
||||
|
||||
private void unsetPermissionInternal(String name) {
|
||||
@ -191,17 +189,13 @@ public class LPPermissionAttachment extends PermissionAttachment {
|
||||
|
||||
// remove transient permissions from the holder which were added by this attachment & equal the permission
|
||||
User user = this.permissible.getUser();
|
||||
if (user.removeIfTransient(n -> n instanceof ImmutableTransientNode && ((ImmutableTransientNode) n).getOwner() == this && n.getPermission().equals(name))) {
|
||||
user.reloadCachedData();
|
||||
}
|
||||
user.removeIfTransient(n -> n instanceof ImmutableTransientNode && ((ImmutableTransientNode) n).getOwner() == this && n.getPermission().equals(name));
|
||||
}
|
||||
|
||||
private void clearInternal() {
|
||||
// remove all transient permissions added by this attachment
|
||||
User user = this.permissible.getUser();
|
||||
if (user.removeIfTransient(n -> n instanceof ImmutableTransientNode && ((ImmutableTransientNode) n).getOwner() == this)) {
|
||||
user.reloadCachedData();
|
||||
}
|
||||
user.removeIfTransient(n -> n instanceof ImmutableTransientNode && ((ImmutableTransientNode) n).getOwner() == this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -32,7 +32,6 @@ import me.lucko.luckperms.common.config.adapter.ConfigurationAdapter;
|
||||
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
|
||||
|
||||
import ninja.leaping.configurate.ConfigurationNode;
|
||||
import ninja.leaping.configurate.SimpleConfigurationNode;
|
||||
import ninja.leaping.configurate.commented.CommentedConfigurationNode;
|
||||
import ninja.leaping.configurate.hocon.HoconConfigurationLoader;
|
||||
import ninja.leaping.configurate.loader.ConfigurationLoader;
|
||||
@ -67,22 +66,11 @@ public class SpongeConfigAdapter extends AbstractConfigurationAdapter implements
|
||||
}
|
||||
|
||||
private ConfigurationNode resolvePath(String path) {
|
||||
Iterable<String> paths = Splitter.on('.').split(path);
|
||||
ConfigurationNode node = this.root;
|
||||
|
||||
if (node == null) {
|
||||
if (this.root == null) {
|
||||
throw new RuntimeException("Config is not loaded.");
|
||||
}
|
||||
|
||||
for (String s : paths) {
|
||||
node = node.getNode(s);
|
||||
|
||||
if (node == null) {
|
||||
return SimpleConfigurationNode.root();
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
return this.root.getNode(Splitter.on('.').splitToList(path).toArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -81,8 +81,6 @@ public class SpongeUserManager extends AbstractUserManager<SpongeUser> implement
|
||||
user.getIoLock().lock();
|
||||
user.getIoLock().unlock();
|
||||
|
||||
// ok, data is here, let's do the pre-calculation stuff.
|
||||
user.preCalculateData();
|
||||
return user.sponge();
|
||||
}
|
||||
|
||||
@ -94,7 +92,6 @@ public class SpongeUserManager extends AbstractUserManager<SpongeUser> implement
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
||||
user.preCalculateData();
|
||||
return user.sponge();
|
||||
});
|
||||
|
||||
|
@ -448,10 +448,7 @@ public class HolderSubjectData implements LPSubjectData {
|
||||
// handle transient first
|
||||
if (this.type == NodeMapType.TRANSIENT) {
|
||||
// don't bother saving to primary storage. just refresh
|
||||
if (t.getType().isUser()) {
|
||||
User user = ((User) t);
|
||||
return user.reloadCachedData();
|
||||
} else {
|
||||
if (t.getType().isGroup()) {
|
||||
return this.service.getPlugin().getUpdateTaskBuffer().request();
|
||||
}
|
||||
}
|
||||
@ -459,26 +456,11 @@ public class HolderSubjectData implements LPSubjectData {
|
||||
// handle enduring
|
||||
if (t.getType().isUser()) {
|
||||
User user = ((User) t);
|
||||
CompletableFuture<Void> fut = new CompletableFuture<>();
|
||||
this.service.getPlugin().getStorage().saveUser(user).whenCompleteAsync((v, ex) -> {
|
||||
if (ex != null) {
|
||||
fut.complete(null);
|
||||
}
|
||||
|
||||
user.reloadCachedData().thenAccept(fut::complete);
|
||||
}, this.service.getPlugin().getBootstrap().getScheduler().async());
|
||||
return fut;
|
||||
return this.service.getPlugin().getStorage().saveUser(user);
|
||||
} else {
|
||||
Group group = ((Group) t);
|
||||
CompletableFuture<Void> fut = new CompletableFuture<>();
|
||||
this.service.getPlugin().getStorage().saveGroup(group).whenCompleteAsync((v, ex) -> {
|
||||
if (ex != null) {
|
||||
fut.complete(null);
|
||||
}
|
||||
|
||||
this.service.getPlugin().getUpdateTaskBuffer().request().thenAccept(fut::complete);
|
||||
}, this.service.getPlugin().getBootstrap().getScheduler().async());
|
||||
return fut;
|
||||
return this.service.getPlugin().getStorage().saveGroup(group)
|
||||
.thenCompose(v -> this.service.getPlugin().getUpdateTaskBuffer().request());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ public class SubjectDataContainer {
|
||||
* @param root the root json object
|
||||
* @return a container representing the json data
|
||||
*/
|
||||
public static SubjectDataContainer derserialize(LPPermissionService service, JsonObject root) {
|
||||
public static SubjectDataContainer deserialize(LPPermissionService service, JsonObject root) {
|
||||
return new SubjectDataContainer(service, root);
|
||||
}
|
||||
|
||||
|
@ -202,7 +202,7 @@ public class SubjectStorage {
|
||||
|
||||
try (BufferedReader reader = Files.newBufferedReader(file, StandardCharsets.UTF_8)) {
|
||||
JsonObject data = this.gson.fromJson(reader, JsonObject.class);
|
||||
SubjectDataContainer model = SubjectDataContainer.derserialize(this.service, data);
|
||||
SubjectDataContainer model = SubjectDataContainer.deserialize(this.service, data);
|
||||
return new LoadedSubject(subjectName, model);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user