Sponge: rely less on dummy subjects
This commit is contained in:
parent
e8cd2c7548
commit
9fe9c386bb
@ -23,9 +23,17 @@
|
|||||||
package me.lucko.luckperms.sponge.service.collections;
|
package me.lucko.luckperms.sponge.service.collections;
|
||||||
|
|
||||||
import co.aikar.timings.Timing;
|
import co.aikar.timings.Timing;
|
||||||
|
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 com.google.common.util.concurrent.UncheckedExecutionException;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import me.lucko.luckperms.api.context.ContextSet;
|
import me.lucko.luckperms.api.context.ContextSet;
|
||||||
|
import me.lucko.luckperms.common.groups.Group;
|
||||||
import me.lucko.luckperms.common.groups.GroupManager;
|
import me.lucko.luckperms.common.groups.GroupManager;
|
||||||
|
import me.lucko.luckperms.common.utils.ArgumentChecker;
|
||||||
import me.lucko.luckperms.common.utils.ImmutableCollectors;
|
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;
|
||||||
@ -40,12 +48,31 @@ import org.spongepowered.api.util.Tristate;
|
|||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
public class GroupCollection implements SubjectCollection {
|
public class GroupCollection implements SubjectCollection {
|
||||||
private final LuckPermsService service;
|
private final LuckPermsService service;
|
||||||
private final GroupManager manager;
|
private final GroupManager manager;
|
||||||
private final SimpleCollection fallback;
|
private final SimpleCollection fallback;
|
||||||
|
|
||||||
|
private final LoadingCache<String, LuckPermsGroupSubject> groups = CacheBuilder.newBuilder()
|
||||||
|
.build(new CacheLoader<String, LuckPermsGroupSubject>() {
|
||||||
|
@Override
|
||||||
|
public LuckPermsGroupSubject load(String id) throws Exception {
|
||||||
|
Group group = manager.get(id);
|
||||||
|
if (group == null) {
|
||||||
|
throw new IllegalStateException("User not loaded");
|
||||||
|
}
|
||||||
|
|
||||||
|
return LuckPermsGroupSubject.wrapGroup(group, service);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ListenableFuture<LuckPermsGroupSubject> reload(String str, LuckPermsGroupSubject s) {
|
||||||
|
return Futures.immediateFuture(s); // Never needs to be refreshed.
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
public GroupCollection(LuckPermsService service, GroupManager manager) {
|
public GroupCollection(LuckPermsService service, GroupManager manager) {
|
||||||
this.service = service;
|
this.service = service;
|
||||||
this.manager = manager;
|
this.manager = manager;
|
||||||
@ -60,24 +87,39 @@ public class GroupCollection implements SubjectCollection {
|
|||||||
@Override
|
@Override
|
||||||
public Subject get(@NonNull String id) {
|
public Subject get(@NonNull String id) {
|
||||||
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.GROUP_COLLECTION_GET)) {
|
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.GROUP_COLLECTION_GET)) {
|
||||||
if (manager.isLoaded(id)) {
|
id = id.toLowerCase();
|
||||||
return LuckPermsGroupSubject.wrapGroup(manager.get(id), service);
|
if (ArgumentChecker.checkName(id)) {
|
||||||
|
service.getPlugin().getLog().warn("Couldn't get group subject for id: " + id + " (invalid name)");
|
||||||
|
return fallback.get(id); // fallback to transient collection
|
||||||
}
|
}
|
||||||
|
|
||||||
return fallback.get(id);
|
// check if the user is loaded in memory. hopefully this call is not on the main thread. :(
|
||||||
|
if (!manager.isLoaded(id)) {
|
||||||
|
service.getPlugin().getLog().warn("Group Subject '" + id + "' was requested, but is not loaded in memory. Loading it from storage now.");
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
service.getPlugin().getDatastore().createAndLoadGroup(id).getUnchecked();
|
||||||
|
service.getPlugin().getLog().warn("Loading '" + id + "' took " + (System.currentTimeMillis() - startTime) + " ms.");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return groups.get(id);
|
||||||
|
} catch (ExecutionException | UncheckedExecutionException e) {
|
||||||
|
service.getPlugin().getLog().warn("Unable to get group subject '" + id + "' from memory.");
|
||||||
|
e.printStackTrace();
|
||||||
|
return fallback.get(id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasRegistered(@NonNull String id) {
|
public boolean hasRegistered(@NonNull String id) {
|
||||||
return manager.isLoaded(id);
|
id = id.toLowerCase();
|
||||||
|
return !ArgumentChecker.checkName(id) && (groups.asMap().containsKey(id) || manager.isLoaded(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterable<Subject> getAllSubjects() {
|
public Iterable<Subject> getAllSubjects() {
|
||||||
return manager.getAll().values().stream()
|
return groups.asMap().values().stream().collect(ImmutableCollectors.toImmutableList());
|
||||||
.map(u -> LuckPermsGroupSubject.wrapGroup(u, service))
|
|
||||||
.collect(ImmutableCollectors.toImmutableList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -88,8 +130,7 @@ 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);
|
ContextSet cs = LuckPermsService.convertContexts(contexts);
|
||||||
return manager.getAll().values().stream()
|
return groups.asMap().values().stream()
|
||||||
.map(u -> LuckPermsGroupSubject.wrapGroup(u, service))
|
|
||||||
.filter(sub -> sub.getPermissionValue(cs, node) != Tristate.UNDEFINED)
|
.filter(sub -> sub.getPermissionValue(cs, node) != Tristate.UNDEFINED)
|
||||||
.collect(ImmutableCollectors.toImmutableMap(sub -> sub, sub -> sub.getPermissionValue(cs, node).asBoolean()));
|
.collect(ImmutableCollectors.toImmutableMap(sub -> sub, sub -> sub.getPermissionValue(cs, node).asBoolean()));
|
||||||
}
|
}
|
||||||
|
@ -33,6 +33,7 @@ import lombok.NonNull;
|
|||||||
import me.lucko.luckperms.api.context.ContextSet;
|
import me.lucko.luckperms.api.context.ContextSet;
|
||||||
import me.lucko.luckperms.common.commands.utils.Util;
|
import me.lucko.luckperms.common.commands.utils.Util;
|
||||||
import me.lucko.luckperms.common.users.User;
|
import me.lucko.luckperms.common.users.User;
|
||||||
|
import me.lucko.luckperms.common.users.UserIdentifier;
|
||||||
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.common.utils.ImmutableCollectors;
|
||||||
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
import me.lucko.luckperms.sponge.service.LuckPermsService;
|
||||||
@ -47,7 +48,6 @@ import org.spongepowered.api.service.permission.SubjectData;
|
|||||||
import org.spongepowered.api.util.Tristate;
|
import org.spongepowered.api.util.Tristate;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
@ -97,50 +97,41 @@ public class UserCollection implements SubjectCollection {
|
|||||||
@Override
|
@Override
|
||||||
public Subject get(@NonNull String id) {
|
public Subject get(@NonNull String id) {
|
||||||
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.USER_COLLECTION_GET)) {
|
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.USER_COLLECTION_GET)) {
|
||||||
Optional<Subject> s = getIfLoaded(id);
|
UUID uuid = Util.parseUuid(id);
|
||||||
if (s.isPresent()) {
|
if (uuid == null) {
|
||||||
return s.get();
|
service.getPlugin().getLog().warn("Couldn't get user subject for id: " + id + " (not a uuid)");
|
||||||
|
return fallback.get(id); // fallback to the transient collection
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fallback to the other collection. This Subject instance will never be persisted.
|
UUID u = service.getPlugin().getUuidCache().getUUID(uuid);
|
||||||
return fallback.get(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Optional<Subject> getIfLoaded(String id) {
|
// check if the user is loaded in memory. hopefully this call is not on the main thread. :(
|
||||||
UUID uuid = Util.parseUuid(id);
|
if (!manager.isLoaded(UserIdentifier.of(u, null))) {
|
||||||
|
service.getPlugin().getLog().warn("User Subject '" + u + "' was requested, but is not loaded in memory. Loading them from storage now.");
|
||||||
find:
|
long startTime = System.currentTimeMillis();
|
||||||
if (uuid == null) {
|
service.getPlugin().getDatastore().loadUser(u, "null").getUnchecked();
|
||||||
for (LuckPermsUserSubject subject : users.asMap().values()) {
|
service.getPlugin().getLog().warn("Loading '" + u + "' took " + (System.currentTimeMillis() - startTime) + " ms.");
|
||||||
if (subject.getUser().getName().equals(id)) {
|
|
||||||
return Optional.of(subject);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (User user : manager.getAll().values()) {
|
try {
|
||||||
if (user.getName().equalsIgnoreCase(id)) {
|
return users.get(u);
|
||||||
uuid = user.getUuid();
|
} catch (ExecutionException | UncheckedExecutionException e) {
|
||||||
break find;
|
service.getPlugin().getLog().warn("Unable to get user subject '" + u + "' from memory.");
|
||||||
}
|
e.printStackTrace();
|
||||||
|
return fallback.get(u.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uuid == null) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
UUID internal = service.getPlugin().getUuidCache().getUUID(uuid);
|
|
||||||
try {
|
|
||||||
return Optional.of(users.get(internal));
|
|
||||||
} catch (ExecutionException | UncheckedExecutionException e) {
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasRegistered(@NonNull String id) {
|
public boolean hasRegistered(@NonNull String id) {
|
||||||
return getIfLoaded(id).isPresent();
|
UUID uuid = Util.parseUuid(id);
|
||||||
|
if (uuid == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UUID internal = service.getPlugin().getUuidCache().getUUID(uuid);
|
||||||
|
return users.asMap().containsKey(internal) || manager.isLoaded(UserIdentifier.of(internal, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Loading…
Reference in New Issue
Block a user