Don't fully unload Sponge user subjects

This commit is contained in:
Luck 2016-10-30 13:21:43 +00:00
parent 1275d0023d
commit e88ea9c13d
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
6 changed files with 69 additions and 46 deletions

View File

@ -80,7 +80,7 @@ public class LuckPermsGroupSubject extends LuckPermsSubject {
} }
@Override @Override
protected Tristate getPermissionValue(ContextSet contexts, String permission) { public Tristate getPermissionValue(ContextSet contexts, String permission) {
Map<String, Boolean> permissions = group.getAllNodesFiltered(service.calculateContexts(contexts)).stream() Map<String, Boolean> permissions = group.getAllNodesFiltered(service.calculateContexts(contexts)).stream()
.map(LocalizedNode::getNode) .map(LocalizedNode::getNode)
.collect(Collectors.toMap(Node::getPermission, Node::getValue)); .collect(Collectors.toMap(Node::getPermission, Node::getValue));

View File

@ -34,11 +34,11 @@ import java.util.Set;
public abstract class LuckPermsSubject implements Subject { public abstract class LuckPermsSubject implements Subject {
protected abstract Tristate getPermissionValue(ContextSet contexts, String permission); public abstract Tristate getPermissionValue(ContextSet contexts, String permission);
protected abstract boolean isChildOf(ContextSet contexts, Subject parent); public abstract boolean isChildOf(ContextSet contexts, Subject parent);
protected abstract List<Subject> getParents(ContextSet contexts); public abstract List<Subject> getParents(ContextSet contexts);
protected abstract Optional<String> getOption(ContextSet contexts, String s); public abstract Optional<String> getOption(ContextSet contexts, String s);
protected abstract ContextSet getActiveContextSet(); public abstract ContextSet getActiveContextSet();
@Override @Override
@Deprecated @Deprecated

View File

@ -97,19 +97,19 @@ public class LuckPermsUserSubject extends LuckPermsSubject {
} }
@Override @Override
protected Tristate getPermissionValue(ContextSet contexts, String permission) { public Tristate getPermissionValue(ContextSet contexts, String permission) {
return !hasData() ? return !hasData() ?
Tristate.UNDEFINED : Tristate.UNDEFINED :
LuckPermsService.convertTristate(user.getUserData().getPermissionData(service.calculateContexts(contexts)).getPermissionValue(permission)); LuckPermsService.convertTristate(user.getUserData().getPermissionData(service.calculateContexts(contexts)).getPermissionValue(permission));
} }
@Override @Override
protected boolean isChildOf(ContextSet contexts, Subject parent) { public boolean isChildOf(ContextSet contexts, Subject parent) {
return parent instanceof LuckPermsGroupSubject && getPermissionValue(contexts, "group." + parent.getIdentifier()).asBoolean(); return parent instanceof LuckPermsGroupSubject && getPermissionValue(contexts, "group." + parent.getIdentifier()).asBoolean();
} }
@Override @Override
protected List<Subject> getParents(ContextSet contexts) { public List<Subject> getParents(ContextSet contexts) {
ImmutableList.Builder<Subject> subjects = ImmutableList.builder(); ImmutableList.Builder<Subject> subjects = ImmutableList.builder();
if (hasData()) { if (hasData()) {
@ -132,7 +132,7 @@ public class LuckPermsUserSubject extends LuckPermsSubject {
} }
@Override @Override
protected Optional<String> getOption(ContextSet contexts, String s) { public Optional<String> getOption(ContextSet contexts, String s) {
if (hasData()) { if (hasData()) {
MetaData data = user.getUserData().getMetaData(service.calculateContexts(contexts)); MetaData data = user.getUserData().getMetaData(service.calculateContexts(contexts));
if (s.equalsIgnoreCase("prefix")) { if (s.equalsIgnoreCase("prefix")) {
@ -161,7 +161,7 @@ public class LuckPermsUserSubject extends LuckPermsSubject {
} }
@Override @Override
protected ContextSet getActiveContextSet() { public ContextSet getActiveContextSet() {
return service.getPlugin().getContextManager().getApplicableContext(this); return service.getPlugin().getContextManager().getApplicableContext(this);
} }
} }

View File

@ -23,7 +23,9 @@
package me.lucko.luckperms.sponge.service.collections; package me.lucko.luckperms.sponge.service.collections;
import lombok.NonNull; import lombok.NonNull;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.common.groups.GroupManager; import me.lucko.luckperms.common.groups.GroupManager;
import me.lucko.luckperms.common.utils.ImmutableCollectors;
import me.lucko.luckperms.sponge.service.LuckPermsGroupSubject; import me.lucko.luckperms.sponge.service.LuckPermsGroupSubject;
import me.lucko.luckperms.sponge.service.LuckPermsService; import me.lucko.luckperms.sponge.service.LuckPermsService;
import me.lucko.luckperms.sponge.service.simple.SimpleCollection; import me.lucko.luckperms.sponge.service.simple.SimpleCollection;
@ -72,7 +74,7 @@ public class GroupCollection implements SubjectCollection {
public Iterable<Subject> getAllSubjects() { public Iterable<Subject> getAllSubjects() {
return manager.getAll().values().stream() return manager.getAll().values().stream()
.map(u -> LuckPermsGroupSubject.wrapGroup(u, service)) .map(u -> LuckPermsGroupSubject.wrapGroup(u, service))
.collect(Collectors.toList()); .collect(ImmutableCollectors.toImmutableList());
} }
@Override @Override
@ -82,10 +84,11 @@ public class GroupCollection implements SubjectCollection {
@Override @Override
public Map<Subject, Boolean> getAllWithPermission(@NonNull Set<Context> contexts, @NonNull String node) { public Map<Subject, Boolean> getAllWithPermission(@NonNull Set<Context> contexts, @NonNull String node) {
ContextSet cs = LuckPermsService.convertContexts(contexts);
return manager.getAll().values().stream() return manager.getAll().values().stream()
.map(u -> LuckPermsGroupSubject.wrapGroup(u, service)) .map(u -> LuckPermsGroupSubject.wrapGroup(u, service))
.filter(sub -> sub.getPermissionValue(contexts, node) != Tristate.UNDEFINED) .filter(sub -> sub.getPermissionValue(cs, node) != Tristate.UNDEFINED)
.collect(Collectors.toMap(sub -> sub, sub -> sub.getPermissionValue(contexts, node).asBoolean())); .collect(Collectors.toMap(sub -> sub, sub -> sub.getPermissionValue(cs, node).asBoolean()));
} }
@Override @Override

View File

@ -22,11 +22,17 @@
package me.lucko.luckperms.sponge.service.collections; package me.lucko.luckperms.sponge.service.collections;
import lombok.Getter; import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.NonNull; import lombok.NonNull;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.common.commands.Util; import me.lucko.luckperms.common.commands.Util;
import me.lucko.luckperms.common.users.User; import me.lucko.luckperms.common.users.User;
import me.lucko.luckperms.common.users.UserManager; import me.lucko.luckperms.common.users.UserManager;
import me.lucko.luckperms.common.utils.ImmutableCollectors;
import me.lucko.luckperms.sponge.service.LuckPermsService; import me.lucko.luckperms.sponge.service.LuckPermsService;
import me.lucko.luckperms.sponge.service.LuckPermsUserSubject; import me.lucko.luckperms.sponge.service.LuckPermsUserSubject;
import me.lucko.luckperms.sponge.service.simple.SimpleCollection; import me.lucko.luckperms.sponge.service.simple.SimpleCollection;
@ -41,8 +47,7 @@ import java.util.Map;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
/** /**
* Manages low level Subject instances for the PermissionService. * Manages low level Subject instances for the PermissionService.
@ -53,8 +58,30 @@ public class UserCollection implements SubjectCollection {
private final UserManager manager; private final UserManager manager;
private final SimpleCollection fallback; private final SimpleCollection fallback;
@Getter private final LoadingCache<UUID, LuckPermsUserSubject> users = CacheBuilder.newBuilder()
private final Map<UUID, LuckPermsUserSubject> users = new ConcurrentHashMap<>(); /*
.removalListener((RemovalListener<UUID, LuckPermsUserSubject>) r -> {
if (r.getValue() != null) {
r.getValue().deprovision();
}
})
*/
.build(new CacheLoader<UUID, LuckPermsUserSubject>() {
@Override
public LuckPermsUserSubject load(UUID uuid) throws Exception {
User user = manager.get(uuid);
if (user == null) {
throw new IllegalStateException("user not loaded");
}
return LuckPermsUserSubject.wrapUser(user, service);
}
@Override
public ListenableFuture<LuckPermsUserSubject> reload(UUID uuid, LuckPermsUserSubject s) {
return Futures.immediateFuture(s); // Never needs to be refreshed.
}
});
public UserCollection(LuckPermsService service, UserManager manager) { public UserCollection(LuckPermsService service, UserManager manager) {
this.service = service; this.service = service;
@ -68,9 +95,7 @@ public class UserCollection implements SubjectCollection {
} }
public void unload(UUID uuid) { public void unload(UUID uuid) {
if (users.containsKey(uuid)) { users.invalidate(uuid);
users.remove(uuid).deprovision();
}
} }
@Override @Override
@ -89,7 +114,7 @@ public class UserCollection implements SubjectCollection {
find: find:
if (uuid == null) { if (uuid == null) {
for (LuckPermsUserSubject subject : users.values()) { for (LuckPermsUserSubject subject : users.asMap().values()) {
if (subject.getUser().getName().equals(id)) { if (subject.getUser().getName().equals(id)) {
return Optional.of(subject); return Optional.of(subject);
} }
@ -103,24 +128,18 @@ public class UserCollection implements SubjectCollection {
} }
} }
if (uuid != null) { if (uuid == null) {
UUID internal = service.getPlugin().getUuidCache().getUUID(uuid);
Subject s = users.computeIfAbsent(internal, u -> {
User user = manager.get(u);
if (user == null) return null;
return LuckPermsUserSubject.wrapUser(user, service);
});
if (s != null) {
return Optional.of(s);
}
}
return Optional.empty(); return Optional.empty();
} }
UUID internal = service.getPlugin().getUuidCache().getUUID(uuid);
try {
return Optional.of(users.get(internal));
} catch (ExecutionException e) {
return Optional.empty();
}
}
@Override @Override
public boolean hasRegistered(@NonNull String id) { public boolean hasRegistered(@NonNull String id) {
return getIfLoaded(id).isPresent(); return getIfLoaded(id).isPresent();
@ -128,7 +147,7 @@ public class UserCollection implements SubjectCollection {
@Override @Override
public Iterable<Subject> getAllSubjects() { public Iterable<Subject> getAllSubjects() {
return users.values().stream().collect(Collectors.toList()); return users.asMap().values().stream().collect(ImmutableCollectors.toImmutableList());
} }
@Override @Override
@ -138,9 +157,10 @@ public class UserCollection implements SubjectCollection {
@Override @Override
public Map<Subject, Boolean> getAllWithPermission(@NonNull Set<Context> contexts, @NonNull String node) { public Map<Subject, Boolean> getAllWithPermission(@NonNull Set<Context> contexts, @NonNull String node) {
return users.values().stream() ContextSet cs = LuckPermsService.convertContexts(contexts);
.filter(sub -> sub.getPermissionValue(contexts, node) != Tristate.UNDEFINED) return users.asMap().values().stream()
.collect(Collectors.toMap(sub -> sub, sub -> sub.getPermissionValue(contexts, node).asBoolean())); .filter(sub -> sub.getPermissionValue(cs, node) != Tristate.UNDEFINED)
.collect(ImmutableCollectors.toImmutableMap(sub -> sub, sub -> sub.getPermissionValue(cs, node).asBoolean()));
} }
@Override @Override

View File

@ -25,9 +25,11 @@ package me.lucko.luckperms.sponge.service.persisted;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader; import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache; import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
import lombok.Getter; import lombok.Getter;
import lombok.NonNull; import lombok.NonNull;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.common.utils.ImmutableCollectors;
import me.lucko.luckperms.sponge.service.LuckPermsService; import me.lucko.luckperms.sponge.service.LuckPermsService;
import org.spongepowered.api.service.context.Context; import org.spongepowered.api.service.context.Context;
import org.spongepowered.api.service.permission.Subject; import org.spongepowered.api.service.permission.Subject;
@ -35,10 +37,8 @@ import org.spongepowered.api.service.permission.SubjectCollection;
import org.spongepowered.api.util.Tristate; import org.spongepowered.api.util.Tristate;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
/** /**
* A simple persistable subject collection * A simple persistable subject collection
@ -78,7 +78,7 @@ public class PersistedCollection implements SubjectCollection {
@Override @Override
public Iterable<Subject> getAllSubjects() { public Iterable<Subject> getAllSubjects() {
return subjects.asMap().values().stream().map(s -> (Subject) s).collect(Collectors.toList()); return subjects.asMap().values().stream().map(s -> (Subject) s).collect(ImmutableCollectors.toImmutableList());
} }
@Override @Override
@ -88,7 +88,7 @@ public class PersistedCollection implements SubjectCollection {
@Override @Override
public Map<Subject, Boolean> getAllWithPermission(@NonNull Set<Context> contexts, @NonNull String node) { public Map<Subject, Boolean> getAllWithPermission(@NonNull Set<Context> contexts, @NonNull String node) {
Map<Subject, Boolean> m = new HashMap<>(); ImmutableMap.Builder<Subject, Boolean> m = ImmutableMap.builder();
for (Subject subject : subjects.asMap().values()) { for (Subject subject : subjects.asMap().values()) {
Tristate ts = subject.getPermissionValue(contexts, node); Tristate ts = subject.getPermissionValue(contexts, node);
if (ts != Tristate.UNDEFINED) { if (ts != Tristate.UNDEFINED) {
@ -96,7 +96,7 @@ public class PersistedCollection implements SubjectCollection {
} }
} }
return m; return m.build();
} }
@Override @Override