Remove context pre-processing (mostly)

This approach isn't very effective when contexts are frequently changing, and it is hard to guess in advance which contexts are going to be in-use.

The Sponge version has proven that this whole system isn't really necessary.

Contexts for 'allow all' and 'global' are still pre-processed, however this should be significantly less work for the server. (even if it is being done async)
This commit is contained in:
Luck
2017-10-12 20:17:52 +01:00
Unverified
parent 9c505e4402
commit 8920396360
15 changed files with 53 additions and 227 deletions
@@ -108,7 +108,7 @@ public final class UserDelegate extends PermissionHolderDelegate implements User
@Override
public void setupDataCache() {
handle.preCalculateData(false);
handle.preCalculateData();
}
@Override
@@ -31,12 +31,10 @@ import lombok.RequiredArgsConstructor;
import com.github.benmanes.caffeine.cache.CacheLoader;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import com.google.common.collect.ImmutableSet;
import me.lucko.luckperms.api.ChatMetaType;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.caching.MetaContexts;
import me.lucko.luckperms.api.caching.PermissionData;
import me.lucko.luckperms.api.caching.UserData;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.contexts.ExtractedContexts;
@@ -59,20 +57,22 @@ public class UserCache implements UserData {
private final User user;
private final LoadingCache<Contexts, PermissionCache> permission = Caffeine.newBuilder()
.expireAfterAccess(10, TimeUnit.MINUTES)
.expireAfterAccess(2, TimeUnit.MINUTES)
.build(new PermissionCacheLoader());
private final LoadingCache<MetaContexts, MetaCache> meta = Caffeine.newBuilder()
.expireAfterAccess(10, TimeUnit.MINUTES)
.expireAfterAccess(2, TimeUnit.MINUTES)
.build(new MetaCacheLoader());
@Override
public PermissionCache getPermissionData(@NonNull Contexts contexts) {
//noinspection ConstantConditions
return permission.get(contexts);
}
@Override
public MetaCache getMetaData(@NonNull MetaContexts contexts) {
//noinspection ConstantConditions
return meta.get(contexts);
}
@@ -131,14 +131,14 @@ public class UserCache implements UserData {
@Override
public void recalculatePermissions() {
Set<Contexts> keys = ImmutableSet.copyOf(permission.asMap().keySet());
keys.forEach(permission::refresh);
Set<Contexts> keys = permission.asMap().keySet();
keys.forEach(this::recalculatePermissions);
}
@Override
public void recalculateMeta() {
Set<MetaContexts> keys = ImmutableSet.copyOf(meta.asMap().keySet());
keys.forEach(meta::refresh);
Set<MetaContexts> keys = meta.asMap().keySet();
keys.forEach(this::recalculateMeta);
}
@Override
@@ -148,30 +148,27 @@ public class UserCache implements UserData {
@Override
public void preCalculate(@NonNull Contexts contexts) {
permission.get(contexts);
meta.get(makeFromMetaContextsConfig(contexts, user.getPlugin()));
// pre-calculate just by requesting the data from this cache.
// if the data isn't already loaded, it will be calculated.
getPermissionData(contexts);
getMetaData(contexts);
}
public void invalidateCache() {
public void invalidateCaches() {
permission.invalidateAll();
meta.invalidateAll();
}
@Override
public void invalidatePermissionCalculators() {
permission.asMap().values().forEach(PermissionData::invalidateCache);
permission.asMap().values().forEach(PermissionCache::invalidateCache);
}
public void cleanup() {
public void doCacheCleanup() {
permission.cleanUp();
meta.cleanUp();
}
public void clear() {
permission.invalidateAll();
meta.invalidateAll();
}
private final class PermissionCacheLoader implements CacheLoader<Contexts, PermissionCache> {
@Override
public PermissionCache load(Contexts contexts) {
@@ -99,7 +99,7 @@ public class GenericUserManager extends AbstractManager<UserIdentifier, User> im
plugin.getScheduler().asyncLater(() -> {
User user = getIfLoaded(plugin.getUuidCache().getUUID(uuid));
if (user != null && !plugin.isPlayerOnline(uuid)) {
user.unregisterData();
user.getUserData().invalidateCaches();
unload(user);
plugin.getUuidCache().clearCache(uuid);
}
@@ -29,6 +29,7 @@ import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.common.api.delegates.UserDelegate;
import me.lucko.luckperms.common.buffers.BufferedRequest;
import me.lucko.luckperms.common.caching.UserCache;
@@ -161,16 +162,14 @@ public class User extends PermissionHolder implements Identifiable<UserIdentifie
* Sets up the UserData cache
* Blocking call.
*/
public synchronized void preCalculateData(boolean op) {
userData.preCalculate(getPlugin().getPreProcessContexts(op));
getPlugin().onUserRefresh(this);
}
public synchronized void preCalculateData() {
// first try to refresh any existing permissions
refreshPermissions();
/**
* Removes the UserData cache from this user
*/
public void unregisterData() {
userData.clear();
// pre-calc the allowall & global contexts
// since contexts change so frequently, it's not worth trying to calculate any more than this.
userData.preCalculate(Contexts.allowAll());
userData.preCalculate(Contexts.global());
}
/**
@@ -205,10 +204,6 @@ public class User extends PermissionHolder implements Identifiable<UserIdentifie
}
}
public void cleanup() {
userData.cleanup();
}
private static final class UserRefreshBuffer extends BufferedRequest<Void> {
private final User user;
@@ -55,8 +55,8 @@ import me.lucko.luckperms.common.verbose.VerboseHandler;
import java.io.File;
import java.io.InputStream;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
@@ -369,14 +369,6 @@ public interface LuckPermsPlugin {
*/
Set<UUID> getUniqueConnections();
/**
* Gets a set of Contexts that should be pre-processed in advance
*
* @param op if the user being processed is op
* @return a set of contexts
*/
Set<Contexts> getPreProcessContexts(boolean op);
default List<Command> getExtraCommands() {
return Collections.emptyList();
}
@@ -386,7 +378,7 @@ public interface LuckPermsPlugin {
*
* @return a map of options, or null
*/
default LinkedHashMap<String, Object> getExtraInfo() {
default Map<String, Object> getExtraInfo() {
return null;
}
@@ -37,7 +37,7 @@ public class CacheHousekeepingTask implements Runnable {
@Override
public void run() {
for (User user : plugin.getUserManager().getAll().values()) {
user.cleanup();
user.getUserData().doCacheCleanup();
}
}
}
@@ -90,7 +90,8 @@ public class LoginHelper {
plugin.getStorage().noBuffer().saveUser(user).join();
}
user.preCalculateData(false); // Pretty nasty calculation call. Sets up the caching system so data is ready when the user joins.
// Does some minimum pre-calculations to (maybe) speed things up later.
user.preCalculateData();
}
final long time = System.currentTimeMillis() - startTime;