Avoid running full "update tasks" unless they're absolutely needed. Process Vault API "set" requests immediately instead of in the background
This commit is contained in:
parent
f0c0328919
commit
3a123f9fa1
@ -50,11 +50,10 @@ import java.util.UUID;
|
|||||||
/**
|
/**
|
||||||
* An implementation of the Vault {@link Chat} API using LuckPerms.
|
* An implementation of the Vault {@link Chat} API using LuckPerms.
|
||||||
*
|
*
|
||||||
* Methods which change the state of data objects are likely to return immediately.
|
|
||||||
*
|
|
||||||
* LuckPerms is a multithreaded permissions plugin, and some actions require considerable
|
* LuckPerms is a multithreaded permissions plugin, and some actions require considerable
|
||||||
* time to execute. (database queries, re-population of caches, etc) In these cases, the
|
* time to execute. (database queries, re-population of caches, etc) In these cases, the
|
||||||
* methods will return immediately and the change will be executed asynchronously.
|
* operations required to make the edit apply will be processed immediately, but the process
|
||||||
|
* of saving the change to the plugin storage will happen in the background.
|
||||||
*
|
*
|
||||||
* Methods that have to query data from the database will throw exceptions when called
|
* Methods that have to query data from the database will throw exceptions when called
|
||||||
* from the main thread. Users of the Vault API expect these methods to be "main thread friendly",
|
* from the main thread. Users of the Vault API expect these methods to be "main thread friendly",
|
||||||
@ -251,27 +250,25 @@ public class VaultChatHook extends AbstractVaultChat {
|
|||||||
logMsg("#setChatMeta: %s - %s - %s - %s", holder.getFriendlyName(), type, value, world);
|
logMsg("#setChatMeta: %s - %s - %s - %s", holder.getFriendlyName(), type, value, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.permissionHook.getExecutor().execute(() -> {
|
// remove all prefixes/suffixes directly set on the user/group
|
||||||
// remove all prefixes/suffixes directly set on the user/group
|
holder.removeIf(type::matches);
|
||||||
holder.removeIf(type::matches);
|
|
||||||
|
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
this.permissionHook.holderSave(holder);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// find the max inherited priority & add 10
|
|
||||||
MetaAccumulator metaAccumulator = holder.accumulateMeta(null, createContextForWorldSet(world));
|
|
||||||
metaAccumulator.complete();
|
|
||||||
int priority = metaAccumulator.getChatMeta(type).keySet().stream().mapToInt(e -> e).max().orElse(0) + 10;
|
|
||||||
|
|
||||||
Node.Builder chatMetaNode = NodeFactory.buildChatMetaNode(type, priority, value);
|
|
||||||
chatMetaNode.setServer(this.permissionHook.getVaultServer());
|
|
||||||
chatMetaNode.setWorld(world);
|
|
||||||
|
|
||||||
holder.setPermission(chatMetaNode.build());
|
|
||||||
this.permissionHook.holderSave(holder);
|
this.permissionHook.holderSave(holder);
|
||||||
});
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find the max inherited priority & add 10
|
||||||
|
MetaAccumulator metaAccumulator = holder.accumulateMeta(null, createContextForWorldSet(world));
|
||||||
|
metaAccumulator.complete();
|
||||||
|
int priority = metaAccumulator.getChatMeta(type).keySet().stream().mapToInt(e -> e).max().orElse(0) + 10;
|
||||||
|
|
||||||
|
Node.Builder chatMetaNode = NodeFactory.buildChatMetaNode(type, priority, value);
|
||||||
|
chatMetaNode.setServer(this.permissionHook.getVaultServer());
|
||||||
|
chatMetaNode.setWorld(world);
|
||||||
|
|
||||||
|
holder.setPermission(chatMetaNode.build()); // assume success
|
||||||
|
this.permissionHook.holderSave(holder);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setMeta(PermissionHolder holder, String key, Object value, String world) {
|
private void setMeta(PermissionHolder holder, String key, Object value, String world) {
|
||||||
@ -279,27 +276,25 @@ public class VaultChatHook extends AbstractVaultChat {
|
|||||||
logMsg("#setMeta: %s - %s - %s - %s", holder.getFriendlyName(), key, value, world);
|
logMsg("#setMeta: %s - %s - %s - %s", holder.getFriendlyName(), key, value, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.permissionHook.getExecutor().execute(() -> {
|
holder.removeIf(n -> n.isMeta() && n.getMeta().getKey().equals(key));
|
||||||
holder.removeIf(n -> n.isMeta() && n.getMeta().getKey().equals(key));
|
|
||||||
|
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
this.permissionHook.holderSave(holder);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Node.Builder metaNode;
|
|
||||||
if (key.equalsIgnoreCase(NodeTypes.PREFIX_KEY) || key.equalsIgnoreCase(NodeTypes.SUFFIX_KEY)) {
|
|
||||||
metaNode = NodeFactory.buildChatMetaNode(ChatMetaType.valueOf(key.toUpperCase()), 100, value.toString());
|
|
||||||
} else {
|
|
||||||
metaNode = NodeFactory.buildMetaNode(key, value.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
metaNode.setServer(this.permissionHook.getVaultServer());
|
|
||||||
metaNode.setWorld(world);
|
|
||||||
|
|
||||||
holder.setPermission(metaNode.build());
|
|
||||||
this.permissionHook.holderSave(holder);
|
this.permissionHook.holderSave(holder);
|
||||||
});
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Node.Builder metaNode;
|
||||||
|
if (key.equalsIgnoreCase(NodeTypes.PREFIX_KEY) || key.equalsIgnoreCase(NodeTypes.SUFFIX_KEY)) {
|
||||||
|
metaNode = NodeFactory.buildChatMetaNode(ChatMetaType.valueOf(key.toUpperCase()), 100, value.toString());
|
||||||
|
} else {
|
||||||
|
metaNode = NodeFactory.buildMetaNode(key, value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
metaNode.setServer(this.permissionHook.getVaultServer());
|
||||||
|
metaNode.setWorld(world);
|
||||||
|
|
||||||
|
holder.setPermission(metaNode.build()); // assume success
|
||||||
|
this.permissionHook.holderSave(holder);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Contexts createContextForWorldSet(String world) {
|
private Contexts createContextForWorldSet(String world) {
|
||||||
|
@ -51,17 +51,14 @@ import java.util.Arrays;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.Executors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of the Vault {@link Permission} API using LuckPerms.
|
* An implementation of the Vault {@link Permission} API using LuckPerms.
|
||||||
*
|
*
|
||||||
* Methods which change the state of data objects are likely to return immediately.
|
|
||||||
*
|
|
||||||
* LuckPerms is a multithreaded permissions plugin, and some actions require considerable
|
* LuckPerms is a multithreaded permissions plugin, and some actions require considerable
|
||||||
* time to execute. (database queries, re-population of caches, etc) In these cases, the
|
* time to execute. (database queries, re-population of caches, etc) In these cases, the
|
||||||
* methods will return immediately and the change will be executed asynchronously.
|
* operations required to make the edit apply will be processed immediately, but the process
|
||||||
|
* of saving the change to the plugin storage will happen in the background.
|
||||||
*
|
*
|
||||||
* Methods that have to query data from the database will throw exceptions when called
|
* Methods that have to query data from the database will throw exceptions when called
|
||||||
* from the main thread. Users of the Vault API expect these methods to be "main thread friendly",
|
* from the main thread. Users of the Vault API expect these methods to be "main thread friendly",
|
||||||
@ -73,12 +70,8 @@ public class VaultPermissionHook extends AbstractVaultPermission {
|
|||||||
// the plugin instance
|
// the plugin instance
|
||||||
private final LPBukkitPlugin plugin;
|
private final LPBukkitPlugin plugin;
|
||||||
|
|
||||||
// an executor for Vault modifications.
|
|
||||||
private final ExecutorService executor;
|
|
||||||
|
|
||||||
public VaultPermissionHook(LPBukkitPlugin plugin) {
|
public VaultPermissionHook(LPBukkitPlugin plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.executor = Executors.newSingleThreadExecutor();
|
|
||||||
this.worldMappingFunction = world -> isIgnoreWorld() ? null : world;
|
this.worldMappingFunction = world -> isIgnoreWorld() ? null : world;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,10 +79,6 @@ public class VaultPermissionHook extends AbstractVaultPermission {
|
|||||||
return this.plugin;
|
return this.plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExecutorService getExecutor() {
|
|
||||||
return this.executor;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return "LuckPerms";
|
return "LuckPerms";
|
||||||
@ -119,9 +108,9 @@ public class VaultPermissionHook extends AbstractVaultPermission {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// lookup a username from the database
|
// lookup a username from the database
|
||||||
UUID uuid = plugin.getStorage().getPlayerUuid(player.toLowerCase()).join();
|
UUID uuid = this.plugin.getStorage().getPlayerUuid(player.toLowerCase()).join();
|
||||||
if (uuid == null) {
|
if (uuid == null) {
|
||||||
uuid = plugin.getBootstrap().lookupUuid(player).orElse(null);
|
uuid = this.plugin.getBootstrap().lookupUuid(player).orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
// unable to find a user, throw an exception
|
// unable to find a user, throw an exception
|
||||||
@ -186,8 +175,7 @@ public class VaultPermissionHook extends AbstractVaultPermission {
|
|||||||
Objects.requireNonNull(permission, "permission");
|
Objects.requireNonNull(permission, "permission");
|
||||||
|
|
||||||
User user = lookupUser(uuid);
|
User user = lookupUser(uuid);
|
||||||
holderAddPermission(user, permission, world);
|
return holderAddPermission(user, permission, world);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -196,8 +184,7 @@ public class VaultPermissionHook extends AbstractVaultPermission {
|
|||||||
Objects.requireNonNull(permission, "permission");
|
Objects.requireNonNull(permission, "permission");
|
||||||
|
|
||||||
User user = lookupUser(uuid);
|
User user = lookupUser(uuid);
|
||||||
holderRemovePermission(user, permission, world);
|
return holderRemovePermission(user, permission, world);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -295,8 +282,7 @@ public class VaultPermissionHook extends AbstractVaultPermission {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
holderAddPermission(group, permission, world);
|
return holderAddPermission(group, permission, world);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -309,8 +295,7 @@ public class VaultPermissionHook extends AbstractVaultPermission {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
holderRemovePermission(group, permission, world);
|
return holderRemovePermission(group, permission, world);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// utility methods for getting user and group instances
|
// utility methods for getting user and group instances
|
||||||
@ -380,7 +365,7 @@ public class VaultPermissionHook extends AbstractVaultPermission {
|
|||||||
|
|
||||||
// utility methods for modifying the state of PermissionHolders
|
// utility methods for modifying the state of PermissionHolders
|
||||||
|
|
||||||
private void holderAddPermission(PermissionHolder holder, String permission, String world) {
|
private boolean holderAddPermission(PermissionHolder holder, String permission, String world) {
|
||||||
Objects.requireNonNull(permission, "permission is null");
|
Objects.requireNonNull(permission, "permission is null");
|
||||||
Preconditions.checkArgument(!permission.isEmpty(), "permission is an empty string");
|
Preconditions.checkArgument(!permission.isEmpty(), "permission is an empty string");
|
||||||
|
|
||||||
@ -388,14 +373,13 @@ public class VaultPermissionHook extends AbstractVaultPermission {
|
|||||||
logMsg("#holderAddPermission: %s - %s - %s", holder.getFriendlyName(), permission, world);
|
logMsg("#holderAddPermission: %s - %s - %s", holder.getFriendlyName(), permission, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.executor.execute(() -> {
|
if (holder.setPermission(NodeFactory.make(permission, true, getVaultServer(), world)).asBoolean()) {
|
||||||
if (holder.setPermission(NodeFactory.make(permission, true, getVaultServer(), world)).asBoolean()) {
|
return holderSave(holder);
|
||||||
holderSave(holder);
|
}
|
||||||
}
|
return false;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void holderRemovePermission(PermissionHolder holder, String permission, String world) {
|
private boolean holderRemovePermission(PermissionHolder holder, String permission, String world) {
|
||||||
Objects.requireNonNull(permission, "permission is null");
|
Objects.requireNonNull(permission, "permission is null");
|
||||||
Preconditions.checkArgument(!permission.isEmpty(), "permission is an empty string");
|
Preconditions.checkArgument(!permission.isEmpty(), "permission is an empty string");
|
||||||
|
|
||||||
@ -403,22 +387,32 @@ public class VaultPermissionHook extends AbstractVaultPermission {
|
|||||||
logMsg("#holderRemovePermission: %s - %s - %s", holder.getFriendlyName(), permission, world);
|
logMsg("#holderRemovePermission: %s - %s - %s", holder.getFriendlyName(), permission, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.executor.execute(() -> {
|
if (holder.unsetPermission(NodeFactory.make(permission, getVaultServer(), world)).asBoolean()) {
|
||||||
if (holder.unsetPermission(NodeFactory.make(permission, getVaultServer(), world)).asBoolean()) {
|
return holderSave(holder);
|
||||||
holderSave(holder);
|
}
|
||||||
}
|
return false;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void holderSave(PermissionHolder holder) {
|
boolean holderSave(PermissionHolder holder) {
|
||||||
if (holder.getType().isUser()) {
|
if (holder.getType().isUser()) {
|
||||||
User u = (User) holder;
|
User u = (User) holder;
|
||||||
|
|
||||||
|
// we don't need to join this call - the save operation
|
||||||
|
// can happen in the background.
|
||||||
this.plugin.getStorage().saveUser(u);
|
this.plugin.getStorage().saveUser(u);
|
||||||
}
|
} else if (holder.getType().isGroup()) {
|
||||||
if (holder.getType().isGroup()) {
|
|
||||||
Group g = (Group) holder;
|
Group g = (Group) holder;
|
||||||
this.plugin.getStorage().saveGroup(g).thenRunAsync(() -> this.plugin.getUpdateTaskBuffer().request(), this.plugin.getBootstrap().getScheduler().async());
|
|
||||||
|
// invalidate caches - they have potentially been affected by
|
||||||
|
// this change.
|
||||||
|
this.plugin.getGroupManager().invalidateAllGroupCaches();
|
||||||
|
this.plugin.getUserManager().invalidateAllUserCaches();
|
||||||
|
|
||||||
|
// we don't need to join this call - the save operation
|
||||||
|
// can happen in the background.
|
||||||
|
this.plugin.getStorage().saveGroup(g);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// helper methods to just pull values from the config.
|
// helper methods to just pull values from the config.
|
||||||
|
@ -130,7 +130,8 @@ public final class StorageAssistant {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
plugin.getUpdateTaskBuffer().requestDirectly();
|
plugin.getGroupManager().invalidateAllGroupCaches();
|
||||||
|
plugin.getUserManager().invalidateAllUserCaches();
|
||||||
|
|
||||||
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)) {
|
||||||
@ -154,7 +155,8 @@ public final class StorageAssistant {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
plugin.getUpdateTaskBuffer().requestDirectly();
|
plugin.getGroupManager().invalidateAllGroupCaches();
|
||||||
|
plugin.getUserManager().invalidateAllUserCaches();
|
||||||
|
|
||||||
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)) {
|
||||||
|
@ -27,6 +27,7 @@ package me.lucko.luckperms.common.managers.group;
|
|||||||
|
|
||||||
import me.lucko.luckperms.common.managers.AbstractManager;
|
import me.lucko.luckperms.common.managers.AbstractManager;
|
||||||
import me.lucko.luckperms.common.model.Group;
|
import me.lucko.luckperms.common.model.Group;
|
||||||
|
import me.lucko.luckperms.common.model.PermissionHolder;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@ -63,4 +64,9 @@ public abstract class AbstractGroupManager<T extends Group> extends AbstractMana
|
|||||||
protected String sanitizeIdentifier(String s) {
|
protected String sanitizeIdentifier(String s) {
|
||||||
return s.toLowerCase();
|
return s.toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invalidateAllGroupCaches() {
|
||||||
|
getAll().values().forEach(PermissionHolder::invalidateCachedData);
|
||||||
|
}
|
||||||
}
|
}
|
@ -38,4 +38,9 @@ public interface GroupManager<T extends Group> extends Manager<String, Group, T>
|
|||||||
*/
|
*/
|
||||||
T getByDisplayName(String name);
|
T getByDisplayName(String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidates the cached data for *loaded* groups.
|
||||||
|
*/
|
||||||
|
void invalidateAllGroupCaches();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ import me.lucko.luckperms.api.Node;
|
|||||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||||
import me.lucko.luckperms.common.config.ConfigKeys;
|
import me.lucko.luckperms.common.config.ConfigKeys;
|
||||||
import me.lucko.luckperms.common.managers.AbstractManager;
|
import me.lucko.luckperms.common.managers.AbstractManager;
|
||||||
|
import me.lucko.luckperms.common.model.PermissionHolder;
|
||||||
import me.lucko.luckperms.common.model.User;
|
import me.lucko.luckperms.common.model.User;
|
||||||
import me.lucko.luckperms.common.model.UserIdentifier;
|
import me.lucko.luckperms.common.model.UserIdentifier;
|
||||||
import me.lucko.luckperms.common.node.factory.NodeFactory;
|
import me.lucko.luckperms.common.node.factory.NodeFactory;
|
||||||
@ -153,6 +154,11 @@ public abstract class AbstractUserManager<T extends User> extends AbstractManage
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void invalidateAllUserCaches() {
|
||||||
|
getAll().values().forEach(PermissionHolder::invalidateCachedData);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether the user's state indicates that they should be persisted to storage.
|
* Check whether the user's state indicates that they should be persisted to storage.
|
||||||
*
|
*
|
||||||
|
@ -80,8 +80,13 @@ public interface UserManager<T extends User> extends Manager<UserIdentifier, Use
|
|||||||
void cleanup(User user);
|
void cleanup(User user);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reloads the data of all online users
|
* Reloads the data of all *online* users
|
||||||
*/
|
*/
|
||||||
CompletableFuture<Void> updateAllUsers();
|
CompletableFuture<Void> updateAllUsers();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidates the cached data for *loaded* users.
|
||||||
|
*/
|
||||||
|
void invalidateAllUserCaches();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,8 @@ public class ExpireTemporaryTask implements Runnable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (groupChanges) {
|
if (groupChanges) {
|
||||||
this.plugin.getUpdateTaskBuffer().request();
|
this.plugin.getGroupManager().invalidateAllGroupCaches();
|
||||||
|
this.plugin.getUserManager().invalidateAllUserCaches();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,6 +70,7 @@ public class UpdateTask implements Runnable {
|
|||||||
this.plugin.getStorage().loadAllTracks().join();
|
this.plugin.getStorage().loadAllTracks().join();
|
||||||
|
|
||||||
// Refresh all online users.
|
// Refresh all online users.
|
||||||
|
this.plugin.getUserManager().invalidateAllUserCaches();
|
||||||
CompletableFuture<Void> userUpdateFut = this.plugin.getUserManager().updateAllUsers();
|
CompletableFuture<Void> userUpdateFut = this.plugin.getUserManager().updateAllUsers();
|
||||||
if (!this.initialUpdate) {
|
if (!this.initialUpdate) {
|
||||||
userUpdateFut.join();
|
userUpdateFut.join();
|
||||||
|
@ -451,7 +451,9 @@ public class HolderSubjectData implements LPSubjectData {
|
|||||||
if (this.type == NodeMapType.TRANSIENT) {
|
if (this.type == NodeMapType.TRANSIENT) {
|
||||||
// don't bother saving to primary storage. just refresh
|
// don't bother saving to primary storage. just refresh
|
||||||
if (t.getType().isGroup()) {
|
if (t.getType().isGroup()) {
|
||||||
return this.service.getPlugin().getUpdateTaskBuffer().request();
|
this.service.getPlugin().getGroupManager().invalidateAllGroupCaches();
|
||||||
|
this.service.getPlugin().getUserManager().invalidateAllUserCaches();
|
||||||
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,8 +463,9 @@ public class HolderSubjectData implements LPSubjectData {
|
|||||||
return this.service.getPlugin().getStorage().saveUser(user);
|
return this.service.getPlugin().getStorage().saveUser(user);
|
||||||
} else {
|
} else {
|
||||||
Group group = ((Group) t);
|
Group group = ((Group) t);
|
||||||
return this.service.getPlugin().getStorage().saveGroup(group)
|
this.service.getPlugin().getGroupManager().invalidateAllGroupCaches();
|
||||||
.thenCompose(v -> this.service.getPlugin().getUpdateTaskBuffer().request());
|
this.service.getPlugin().getUserManager().invalidateAllUserCaches();
|
||||||
|
return this.service.getPlugin().getStorage().saveGroup(group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user