mirror of
https://github.com/LuckPerms/LuckPerms.git
synced 2024-12-28 03:57:36 +01:00
Refactor sponge cache invalidation
This commit is contained in:
parent
ec75fdddb5
commit
1bd7e5c9c4
@ -85,9 +85,5 @@ public interface LPPermissionService {
|
||||
|
||||
Contexts calculateContexts(ImmutableContextSet contextSet);
|
||||
|
||||
void invalidatePermissionCaches();
|
||||
|
||||
void invalidateParentCaches();
|
||||
|
||||
void invalidateOptionCaches();
|
||||
void invalidateAllCaches(LPSubject.CacheLevel cacheLevel);
|
||||
}
|
||||
|
@ -86,4 +86,17 @@ public interface LPSubject {
|
||||
|
||||
}
|
||||
|
||||
void invalidateCaches(CacheLevel cacheLevel);
|
||||
|
||||
/**
|
||||
* The level of cache for invalidation
|
||||
*
|
||||
* Invalidating at {@link #PARENT} will also invalidate at
|
||||
* {@link #PERMISSION} and {@link #OPTION}, and invalidating at
|
||||
* {@link #PERMISSION} will also invalidate at {@link #OPTION}.
|
||||
*/
|
||||
enum CacheLevel {
|
||||
PARENT, PERMISSION, OPTION
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -78,6 +78,7 @@ import me.lucko.luckperms.sponge.managers.SpongeUserManager;
|
||||
import me.lucko.luckperms.sponge.messaging.SpongeMessagingFactory;
|
||||
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
||||
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubject;
|
||||
import me.lucko.luckperms.sponge.service.model.LPSubjectCollection;
|
||||
import me.lucko.luckperms.sponge.service.persisted.PersistedCollection;
|
||||
import me.lucko.luckperms.sponge.tasks.ServiceCacheHousekeepingTask;
|
||||
@ -332,7 +333,7 @@ public class LPSpongePlugin implements LuckPermsPlugin {
|
||||
((PersistedCollection) collection).loadAll();
|
||||
}
|
||||
}
|
||||
service.invalidateParentCaches();
|
||||
service.invalidateAllCaches(LPSubject.CacheLevel.PARENT);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -27,7 +27,6 @@ package me.lucko.luckperms.sponge.managers;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
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.base.Preconditions;
|
||||
@ -71,17 +70,7 @@ public class SpongeGroupManager implements GroupManager, LPSubjectCollection {
|
||||
private SubjectCollection spongeProxy = null;
|
||||
|
||||
private final LoadingCache<String, SpongeGroup> objects = Caffeine.newBuilder()
|
||||
.build(new CacheLoader<String, SpongeGroup>() {
|
||||
@Override
|
||||
public SpongeGroup load(String i) {
|
||||
return apply(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpongeGroup reload(String i, SpongeGroup t) {
|
||||
return t; // Never needs to be refreshed.
|
||||
}
|
||||
});
|
||||
.build(this::apply);
|
||||
|
||||
private final LoadingCache<String, LPSubject> subjectLoadingCache = Caffeine.newBuilder()
|
||||
.expireAfterWrite(1, TimeUnit.MINUTES)
|
||||
|
@ -27,7 +27,6 @@ package me.lucko.luckperms.sponge.managers;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
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.base.Preconditions;
|
||||
@ -72,17 +71,7 @@ public class SpongeUserManager implements UserManager, LPSubjectCollection {
|
||||
private SubjectCollection spongeProxy = null;
|
||||
|
||||
private final LoadingCache<UserIdentifier, SpongeUser> objects = Caffeine.newBuilder()
|
||||
.build(new CacheLoader<UserIdentifier, SpongeUser>() {
|
||||
@Override
|
||||
public SpongeUser load(UserIdentifier i) {
|
||||
return apply(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpongeUser reload(UserIdentifier i, SpongeUser t) {
|
||||
return t; // Never needs to be refreshed.
|
||||
}
|
||||
});
|
||||
.build(this::apply);
|
||||
|
||||
private final LoadingCache<UUID, LPSubject> subjectLoadingCache = Caffeine.<UUID, LPSubject>newBuilder()
|
||||
.expireAfterWrite(1, TimeUnit.MINUTES)
|
||||
|
@ -126,10 +126,15 @@ public class SpongeGroup extends Group {
|
||||
this.subjectData = new LuckPermsSubjectData(true, plugin.getService(), parent, this);
|
||||
this.transientSubjectData = new LuckPermsSubjectData(false, plugin.getService(), parent, this);
|
||||
|
||||
parent.getStateListeners().add(this::invalidateCaches);
|
||||
parent.getStateListeners().add(() -> invalidateCaches(CacheLevel.PERMISSION));
|
||||
}
|
||||
|
||||
public void invalidateCaches() {
|
||||
@Override
|
||||
public void invalidateCaches(CacheLevel type) {
|
||||
if (type == CacheLevel.OPTION) {
|
||||
return; // don't invalidate for option changes
|
||||
}
|
||||
|
||||
permissionCache.invalidateAll();
|
||||
parentCache.invalidateAll();
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ public class SpongeUser extends User {
|
||||
return this.spongeData;
|
||||
}
|
||||
|
||||
public static class UserSubject implements LPSubject {
|
||||
public static final class UserSubject implements LPSubject {
|
||||
private final SpongeUser parent;
|
||||
private final LPSpongePlugin plugin;
|
||||
|
||||
@ -187,6 +187,12 @@ public class SpongeUser extends User {
|
||||
public ImmutableContextSet getActiveContextSet() {
|
||||
return plugin.getContextManager().getApplicableContext(this.sponge());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateCaches(CacheLevel cacheLevel) {
|
||||
// invalidate for all changes
|
||||
parent.getUserData().invalidateCache();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -34,23 +34,15 @@ import com.github.benmanes.caffeine.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.MapMaker;
|
||||
|
||||
import me.lucko.luckperms.api.Contexts;
|
||||
import me.lucko.luckperms.api.Tristate;
|
||||
import me.lucko.luckperms.api.context.ImmutableContextSet;
|
||||
import me.lucko.luckperms.common.caching.UserCache;
|
||||
import me.lucko.luckperms.common.model.Group;
|
||||
import me.lucko.luckperms.common.model.User;
|
||||
import me.lucko.luckperms.common.utils.Predicates;
|
||||
import me.lucko.luckperms.sponge.LPSpongePlugin;
|
||||
import me.lucko.luckperms.sponge.contexts.SpongeCalculatorLink;
|
||||
import me.lucko.luckperms.sponge.managers.SpongeGroupManager;
|
||||
import me.lucko.luckperms.sponge.managers.SpongeUserManager;
|
||||
import me.lucko.luckperms.sponge.model.SpongeGroup;
|
||||
import me.lucko.luckperms.sponge.service.calculated.CalculatedSubjectData;
|
||||
import me.lucko.luckperms.sponge.service.calculated.OptionLookup;
|
||||
import me.lucko.luckperms.sponge.service.calculated.PermissionLookup;
|
||||
import me.lucko.luckperms.sponge.service.legacy.LegacyDataMigrator;
|
||||
import me.lucko.luckperms.sponge.service.model.LPPermissionDescription;
|
||||
import me.lucko.luckperms.sponge.service.model.LPPermissionService;
|
||||
@ -95,11 +87,6 @@ public class LuckPermsService implements LPPermissionService {
|
||||
private final PersistedCollection defaultSubjects;
|
||||
private final Set<LPPermissionDescription> descriptionSet;
|
||||
|
||||
private final Set<LoadingCache<PermissionLookup, Tristate>> localPermissionCaches;
|
||||
private final Set<LoadingCache<ImmutableContextSet, ImmutableList<SubjectReference>>> localParentCaches;
|
||||
private final Set<LoadingCache<OptionLookup, Optional<String>>> localOptionCaches;
|
||||
private final Set<CalculatedSubjectData> localDataCaches;
|
||||
|
||||
@Getter(value = AccessLevel.NONE)
|
||||
private final LoadingCache<String, LPSubjectCollection> collections = Caffeine.newBuilder()
|
||||
.build(s -> new PersistedCollection(this, s));
|
||||
@ -108,11 +95,6 @@ public class LuckPermsService implements LPPermissionService {
|
||||
this.plugin = plugin;
|
||||
this.spongeProxy = ProxyFactory.toSponge(this);
|
||||
|
||||
localPermissionCaches = Collections.newSetFromMap(new MapMaker().weakKeys().makeMap());
|
||||
localParentCaches = Collections.newSetFromMap(new MapMaker().weakKeys().makeMap());
|
||||
localOptionCaches = Collections.newSetFromMap(new MapMaker().weakKeys().makeMap());
|
||||
localDataCaches = Collections.newSetFromMap(new MapMaker().weakKeys().makeMap());
|
||||
|
||||
storage = new SubjectStorage(this, new File(plugin.getDataDirectory(), "sponge-data"));
|
||||
new LegacyDataMigrator(plugin, new File(plugin.getDataDirectory(), "local"), storage).run();
|
||||
|
||||
@ -254,44 +236,15 @@ public class LuckPermsService implements LPPermissionService {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidatePermissionCaches() {
|
||||
for (LoadingCache<PermissionLookup, Tristate> c : localPermissionCaches) {
|
||||
c.invalidateAll();
|
||||
}
|
||||
for (CalculatedSubjectData subjectData : localDataCaches) {
|
||||
subjectData.invalidateLookupCache();
|
||||
public void invalidateAllCaches(LPSubject.CacheLevel cacheLevel) {
|
||||
for (LPSubjectCollection collection : collections.asMap().values()) {
|
||||
for (LPSubject subject : collection.getLoadedSubjects()) {
|
||||
subject.invalidateCaches(cacheLevel);
|
||||
}
|
||||
}
|
||||
|
||||
plugin.getCalculatorFactory().invalidateAll();
|
||||
|
||||
for (User user : plugin.getUserManager().getAll().values()) {
|
||||
UserCache userCache = user.getUserData();
|
||||
userCache.invalidateCache();
|
||||
}
|
||||
|
||||
for (SpongeGroup group : plugin.getGroupManager().getAll().values()) {
|
||||
group.sponge().invalidateCaches();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateParentCaches() {
|
||||
for (LoadingCache<ImmutableContextSet, ImmutableList<SubjectReference>> c : localParentCaches) {
|
||||
c.invalidateAll();
|
||||
}
|
||||
invalidateOptionCaches();
|
||||
invalidatePermissionCaches();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invalidateOptionCaches() {
|
||||
for (LoadingCache<OptionLookup, Optional<String>> c : localOptionCaches) {
|
||||
c.invalidateAll();
|
||||
}
|
||||
|
||||
for (User user : plugin.getUserManager().getAll().values()) {
|
||||
UserCache userCache = user.getUserData();
|
||||
userCache.invalidateCache();
|
||||
if (cacheLevel != LPSubject.CacheLevel.OPTION) {
|
||||
plugin.getCalculatorFactory().invalidateAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ public class CalculatedSubjectData implements LPSubjectData {
|
||||
permissions.put(e.getKey(), new ConcurrentHashMap<>(e.getValue()));
|
||||
}
|
||||
permissionCache.invalidateAll();
|
||||
service.invalidatePermissionCaches();
|
||||
service.invalidateAllCaches(LPSubject.CacheLevel.PERMISSION);
|
||||
}
|
||||
|
||||
public void replaceParents(Map<ImmutableContextSet, List<SubjectReference>> map) {
|
||||
@ -120,7 +120,7 @@ public class CalculatedSubjectData implements LPSubjectData {
|
||||
set.addAll(e.getValue());
|
||||
parents.put(e.getKey(), set);
|
||||
}
|
||||
service.invalidateParentCaches();
|
||||
service.invalidateAllCaches(LPSubject.CacheLevel.PARENT);
|
||||
}
|
||||
|
||||
public void replaceOptions(Map<ImmutableContextSet, Map<String, String>> map) {
|
||||
@ -128,7 +128,7 @@ public class CalculatedSubjectData implements LPSubjectData {
|
||||
for (Map.Entry<ImmutableContextSet, Map<String, String>> e : map.entrySet()) {
|
||||
options.put(e.getKey(), new ConcurrentHashMap<>(e.getValue()));
|
||||
}
|
||||
service.invalidateOptionCaches();
|
||||
service.invalidateAllCaches(LPSubject.CacheLevel.OPTION);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -152,7 +152,7 @@ public class CalculatedSubjectData implements LPSubjectData {
|
||||
}
|
||||
if (b) {
|
||||
permissionCache.invalidateAll();
|
||||
service.invalidatePermissionCaches();
|
||||
service.invalidateAllCaches(LPSubject.CacheLevel.PERMISSION);
|
||||
}
|
||||
return CompletableFuture.completedFuture(b);
|
||||
}
|
||||
@ -164,7 +164,7 @@ public class CalculatedSubjectData implements LPSubjectData {
|
||||
} else {
|
||||
permissions.clear();
|
||||
permissionCache.invalidateAll();
|
||||
service.invalidatePermissionCaches();
|
||||
service.invalidateAllCaches(LPSubject.CacheLevel.PERMISSION);
|
||||
return CompletableFuture.completedFuture(true);
|
||||
}
|
||||
}
|
||||
@ -179,7 +179,7 @@ public class CalculatedSubjectData implements LPSubjectData {
|
||||
permissions.remove(contexts);
|
||||
if (!perms.isEmpty()) {
|
||||
permissionCache.invalidateAll();
|
||||
service.invalidatePermissionCaches();
|
||||
service.invalidateAllCaches(LPSubject.CacheLevel.PERMISSION);
|
||||
return CompletableFuture.completedFuture(true);
|
||||
}
|
||||
return CompletableFuture.completedFuture(false);
|
||||
@ -199,7 +199,7 @@ public class CalculatedSubjectData implements LPSubjectData {
|
||||
Set<SubjectReference> set = parents.computeIfAbsent(contexts, c -> ConcurrentHashMap.newKeySet());
|
||||
boolean b = set.add(parent);
|
||||
if (b) {
|
||||
service.invalidateParentCaches();
|
||||
service.invalidateAllCaches(LPSubject.CacheLevel.PARENT);
|
||||
}
|
||||
return CompletableFuture.completedFuture(b);
|
||||
}
|
||||
@ -209,7 +209,7 @@ public class CalculatedSubjectData implements LPSubjectData {
|
||||
Set<SubjectReference> set = parents.get(contexts);
|
||||
boolean b = set != null && set.remove(parent);
|
||||
if (b) {
|
||||
service.invalidateParentCaches();
|
||||
service.invalidateAllCaches(LPSubject.CacheLevel.PARENT);
|
||||
}
|
||||
return CompletableFuture.completedFuture(b);
|
||||
}
|
||||
@ -220,7 +220,7 @@ public class CalculatedSubjectData implements LPSubjectData {
|
||||
return CompletableFuture.completedFuture(false);
|
||||
} else {
|
||||
parents.clear();
|
||||
service.invalidateOptionCaches();
|
||||
service.invalidateAllCaches(LPSubject.CacheLevel.PARENT);
|
||||
return CompletableFuture.completedFuture(true);
|
||||
}
|
||||
}
|
||||
@ -233,7 +233,7 @@ public class CalculatedSubjectData implements LPSubjectData {
|
||||
}
|
||||
|
||||
parents.remove(contexts);
|
||||
service.invalidateParentCaches();
|
||||
service.invalidateAllCaches(LPSubject.CacheLevel.PARENT);
|
||||
return CompletableFuture.completedFuture(!set.isEmpty());
|
||||
}
|
||||
|
||||
@ -251,7 +251,7 @@ public class CalculatedSubjectData implements LPSubjectData {
|
||||
Map<String, String> options = this.options.computeIfAbsent(contexts, c -> new ConcurrentHashMap<>());
|
||||
boolean b = !stringEquals(options.put(key.toLowerCase(), value), value);
|
||||
if (b) {
|
||||
service.invalidateOptionCaches();
|
||||
service.invalidateAllCaches(LPSubject.CacheLevel.OPTION);
|
||||
}
|
||||
return CompletableFuture.completedFuture(b);
|
||||
}
|
||||
@ -261,7 +261,7 @@ public class CalculatedSubjectData implements LPSubjectData {
|
||||
Map<String, String> options = this.options.get(contexts);
|
||||
boolean b = options != null && options.remove(key.toLowerCase()) != null;
|
||||
if (b) {
|
||||
service.invalidateOptionCaches();
|
||||
service.invalidateAllCaches(LPSubject.CacheLevel.OPTION);
|
||||
}
|
||||
return CompletableFuture.completedFuture(b);
|
||||
}
|
||||
@ -272,7 +272,7 @@ public class CalculatedSubjectData implements LPSubjectData {
|
||||
return CompletableFuture.completedFuture(false);
|
||||
} else {
|
||||
options.clear();
|
||||
service.invalidateOptionCaches();
|
||||
service.invalidateAllCaches(LPSubject.CacheLevel.OPTION);
|
||||
return CompletableFuture.completedFuture(true);
|
||||
}
|
||||
}
|
||||
@ -285,7 +285,7 @@ public class CalculatedSubjectData implements LPSubjectData {
|
||||
}
|
||||
|
||||
options.remove(contexts);
|
||||
service.invalidateOptionCaches();
|
||||
service.invalidateAllCaches(LPSubject.CacheLevel.OPTION);
|
||||
return CompletableFuture.completedFuture(!map.isEmpty());
|
||||
}
|
||||
|
||||
|
@ -98,14 +98,27 @@ public class PersistedSubject implements LPSubject {
|
||||
this.service = service;
|
||||
this.parentCollection = parentCollection;
|
||||
|
||||
this.subjectData = new PersistedSubjectData(service, "local:" + parentCollection.getIdentifier() + "/" + identifier + "(p)", this);
|
||||
this.transientSubjectData = new CalculatedSubjectData(this, service, "local:" + parentCollection.getIdentifier() + "/" + identifier + "(t)");
|
||||
this.subjectData = new PersistedSubjectData(service, parentCollection.getIdentifier() + "/" + identifier + "/p", this);
|
||||
this.transientSubjectData = new CalculatedSubjectData(this, service, parentCollection.getIdentifier() + "/" + identifier + "/t");
|
||||
}
|
||||
|
||||
service.getLocalDataCaches().add(subjectData);
|
||||
service.getLocalDataCaches().add(transientSubjectData);
|
||||
service.getLocalPermissionCaches().add(permissionLookupCache);
|
||||
service.getLocalParentCaches().add(parentLookupCache);
|
||||
service.getLocalOptionCaches().add(optionLookupCache);
|
||||
@Override
|
||||
public void invalidateCaches(CacheLevel type) {
|
||||
optionLookupCache.invalidateAll();
|
||||
|
||||
if (type == CacheLevel.OPTION) {
|
||||
return;
|
||||
}
|
||||
|
||||
permissionLookupCache.invalidateAll();
|
||||
subjectData.invalidateLookupCache();
|
||||
transientSubjectData.invalidateLookupCache();
|
||||
|
||||
if (type == CacheLevel.PERMISSION) {
|
||||
return;
|
||||
}
|
||||
|
||||
parentLookupCache.invalidateAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
Reference in New Issue
Block a user