Hopefully fix #118
This commit is contained in:
parent
bd509b3c75
commit
a23f995717
@ -30,6 +30,7 @@ import com.google.common.cache.LoadingCache;
|
|||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.util.concurrent.Futures;
|
import com.google.common.util.concurrent.Futures;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
import com.google.common.util.concurrent.UncheckedExecutionException;
|
||||||
|
|
||||||
import me.lucko.luckperms.api.Tristate;
|
import me.lucko.luckperms.api.Tristate;
|
||||||
import me.lucko.luckperms.api.context.ContextSet;
|
import me.lucko.luckperms.api.context.ContextSet;
|
||||||
@ -51,6 +52,8 @@ import co.aikar.timings.Timing;
|
|||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
public class SpongeGroupManager implements GroupManager, LPSubjectCollection {
|
public class SpongeGroupManager implements GroupManager, LPSubjectCollection {
|
||||||
private final LPSpongePlugin plugin;
|
private final LPSpongePlugin plugin;
|
||||||
@ -68,6 +71,28 @@ public class SpongeGroupManager implements GroupManager, LPSubjectCollection {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
private final LoadingCache<String, LPSubject> subjectLoadingCache = CacheBuilder.newBuilder()
|
||||||
|
.expireAfterWrite(1, TimeUnit.MINUTES)
|
||||||
|
.build(new CacheLoader<String, LPSubject>() {
|
||||||
|
@Override
|
||||||
|
public LPSubject load(String s) throws Exception {
|
||||||
|
if (isLoaded(s)) {
|
||||||
|
return getIfLoaded(s).getSpongeData();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request load
|
||||||
|
plugin.getStorage().createAndLoadGroup(s).join();
|
||||||
|
|
||||||
|
SpongeGroup group = getIfLoaded(s);
|
||||||
|
if (group == null) {
|
||||||
|
plugin.getLog().severe("Error whilst loading group '" + s + "'.");
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return group.getSpongeData();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
public SpongeGroupManager(LPSpongePlugin plugin) {
|
public SpongeGroupManager(LPSpongePlugin plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
@ -138,24 +163,12 @@ public class SpongeGroupManager implements GroupManager, LPSubjectCollection {
|
|||||||
return plugin.getService().getFallbackGroupSubjects().get(id); // fallback to transient collection
|
return plugin.getService().getFallbackGroupSubjects().get(id); // fallback to transient collection
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if the group is loaded in memory.
|
try {
|
||||||
if (isLoaded(id)) {
|
return subjectLoadingCache.get(id);
|
||||||
return getIfLoaded(id).getSpongeData();
|
} catch (UncheckedExecutionException | ExecutionException e) {
|
||||||
} else {
|
e.printStackTrace();
|
||||||
|
plugin.getLog().warn("Couldn't get group subject for id: " + id);
|
||||||
// Group isn't already loaded. hopefully this call is not on the main thread. :(
|
return plugin.getService().getFallbackGroupSubjects().get(id); // fallback to the transient collection
|
||||||
//plugin.getLog().warn("Group Subject '" + id + "' was requested, but is not loaded in memory. Loading it from storage now.");
|
|
||||||
long startTime = System.currentTimeMillis();
|
|
||||||
plugin.getStorage().createAndLoadGroup(id).join();
|
|
||||||
SpongeGroup group = getIfLoaded(id);
|
|
||||||
|
|
||||||
if (group == null) {
|
|
||||||
plugin.getLog().severe("Error whilst loading group '" + id + "'.");
|
|
||||||
return plugin.getService().getFallbackGroupSubjects().get(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
//plugin.getLog().warn("Loading '" + id + "' took " + (System.currentTimeMillis() - startTime) + " ms.");
|
|
||||||
return group.getSpongeData();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@ import com.google.common.cache.LoadingCache;
|
|||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.util.concurrent.Futures;
|
import com.google.common.util.concurrent.Futures;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
import com.google.common.util.concurrent.UncheckedExecutionException;
|
||||||
|
|
||||||
import me.lucko.luckperms.api.Tristate;
|
import me.lucko.luckperms.api.Tristate;
|
||||||
import me.lucko.luckperms.api.context.ContextSet;
|
import me.lucko.luckperms.api.context.ContextSet;
|
||||||
@ -52,22 +53,16 @@ import org.spongepowered.api.service.permission.PermissionService;
|
|||||||
import co.aikar.timings.Timing;
|
import co.aikar.timings.Timing;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
|
||||||
|
|
||||||
public class SpongeUserManager implements UserManager, LPSubjectCollection {
|
public class SpongeUserManager implements UserManager, LPSubjectCollection {
|
||||||
private final LPSpongePlugin plugin;
|
private final LPSpongePlugin plugin;
|
||||||
|
|
||||||
private final ReentrantLock loadingLock = new ReentrantLock();
|
|
||||||
private final Map<UUID, CountDownLatch> loadingLatches = Collections.synchronizedMap(new HashMap<>());
|
|
||||||
|
|
||||||
private final LoadingCache<UserIdentifier, SpongeUser> objects = CacheBuilder.newBuilder()
|
private final LoadingCache<UserIdentifier, SpongeUser> objects = CacheBuilder.newBuilder()
|
||||||
.build(new CacheLoader<UserIdentifier, SpongeUser>() {
|
.build(new CacheLoader<UserIdentifier, SpongeUser>() {
|
||||||
@Override
|
@Override
|
||||||
@ -81,6 +76,40 @@ public class SpongeUserManager implements UserManager, LPSubjectCollection {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
private final LoadingCache<UUID, LPSubject> subjectLoadingCache = CacheBuilder.newBuilder()
|
||||||
|
.expireAfterWrite(1, TimeUnit.MINUTES)
|
||||||
|
.build(new CacheLoader<UUID, LPSubject>() {
|
||||||
|
@Override
|
||||||
|
public LPSubject load(UUID u) throws Exception {
|
||||||
|
if (isLoaded(UserIdentifier.of(u, null))) {
|
||||||
|
|
||||||
|
SpongeUser user = get(u);
|
||||||
|
if (user.getUserData() == null) {
|
||||||
|
user.setupData(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return get(u).getSpongeData();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Request load
|
||||||
|
plugin.getStorage().loadUser(u, "null").join();
|
||||||
|
|
||||||
|
SpongeUser user = get(u);
|
||||||
|
if (user == null) {
|
||||||
|
plugin.getLog().severe("Error whilst loading user '" + u + "'.");
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
user.setupData(false);
|
||||||
|
|
||||||
|
if (user.getUserData() == null) {
|
||||||
|
plugin.getLog().warn("User data not present for requested user id: " + u);
|
||||||
|
}
|
||||||
|
|
||||||
|
return user.getSpongeData();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
public SpongeUserManager(LPSpongePlugin plugin) {
|
public SpongeUserManager(LPSpongePlugin plugin) {
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
}
|
}
|
||||||
@ -209,69 +238,13 @@ public class SpongeUserManager implements UserManager, LPSubjectCollection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
UUID u = plugin.getUuidCache().getUUID(uuid);
|
UUID u = plugin.getUuidCache().getUUID(uuid);
|
||||||
|
|
||||||
CountDownLatch latch;
|
|
||||||
|
|
||||||
loadingLock.lock();
|
|
||||||
try {
|
try {
|
||||||
boolean loaded = isLoaded(UserIdentifier.of(u, null));
|
return subjectLoadingCache.get(u);
|
||||||
boolean locked = loadingLatches.containsKey(u);
|
} catch (UncheckedExecutionException | ExecutionException e) {
|
||||||
|
|
||||||
if (loaded && !locked) {
|
|
||||||
return get(u).getSpongeData();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!loaded && !locked) {
|
|
||||||
latch = new CountDownLatch(1);
|
|
||||||
loadingLatches.put(u, latch);
|
|
||||||
|
|
||||||
// Request load.
|
|
||||||
plugin.doAsync(() -> {
|
|
||||||
try {
|
|
||||||
plugin.getStorage().loadUser(u, "null").get();
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
SpongeUser user = get(u);
|
|
||||||
if (user == null) {
|
|
||||||
plugin.getLog().severe("Error whilst loading user '" + u + "'.");
|
|
||||||
latch.countDown();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
user.setupData(false);
|
|
||||||
latch.countDown();
|
|
||||||
loadingLatches.remove(u, latch);
|
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// wait for the lock, then load.
|
|
||||||
latch = loadingLatches.get(u);
|
|
||||||
}
|
|
||||||
|
|
||||||
} finally {
|
|
||||||
loadingLock.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait for the task loading the user.
|
|
||||||
try {
|
|
||||||
latch.await(10, TimeUnit.SECONDS);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
plugin.getLog().warn("Couldn't get user subject for id: " + id);
|
||||||
|
|
||||||
SpongeUser user = get(u);
|
|
||||||
if (user == null) {
|
|
||||||
plugin.getLog().warn("Failed to load user subject for id: " + id);
|
|
||||||
return plugin.getService().getFallbackUserSubjects().get(id); // fallback to the transient collection
|
return plugin.getService().getFallbackUserSubjects().get(id); // fallback to the transient collection
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user.getUserData() == null) {
|
|
||||||
plugin.getLog().warn("User data not present for requested user id: " + id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return user.getSpongeData();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +94,12 @@ public class SpongeUser extends User {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasData() {
|
private boolean hasData() {
|
||||||
return parent.getUserData() != null;
|
if (parent.getUserData() != null) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
plugin.getLog().warn("User " + parent.getName() + " - " + parent.getUuid() + " does not have any data loaded.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -250,7 +250,9 @@ public class PersistedSubject implements LPSubject {
|
|||||||
@Override
|
@Override
|
||||||
public Tristate getPermissionValue(@NonNull ContextSet contexts, @NonNull String node) {
|
public Tristate getPermissionValue(@NonNull ContextSet contexts, @NonNull String node) {
|
||||||
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.INTERNAL_SUBJECT_GET_PERMISSION_VALUE)) {
|
try (Timing ignored = service.getPlugin().getTimings().time(LPTiming.INTERNAL_SUBJECT_GET_PERMISSION_VALUE)) {
|
||||||
return permissionLookupCache.getUnchecked(PermissionLookup.of(node, contexts.makeImmutable()));
|
Tristate t = permissionLookupCache.getUnchecked(PermissionLookup.of(node, contexts.makeImmutable()));
|
||||||
|
service.getPlugin().getDebugHandler().offer("local:" + getParentCollection().getCollection() + "/" + identifier, node, t);
|
||||||
|
return t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user