mirror of
https://github.com/LuckPerms/LuckPerms.git
synced 2024-11-24 11:38:40 +01:00
Fix issue where only the first request for a user subject would wait for the loading task to complete. Closes #108
This commit is contained in:
parent
2dad9f84fc
commit
2ce5679373
@ -52,14 +52,22 @@ import org.spongepowered.api.service.permission.PermissionService;
|
||||
import co.aikar.timings.Timing;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
public class SpongeUserManager implements UserManager, LPSubjectCollection {
|
||||
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()
|
||||
.build(new CacheLoader<UserIdentifier, SpongeUser>() {
|
||||
@Override
|
||||
@ -202,26 +210,68 @@ public class SpongeUserManager implements UserManager, LPSubjectCollection {
|
||||
|
||||
UUID u = plugin.getUuidCache().getUUID(uuid);
|
||||
|
||||
// check if the user is loaded in memory.
|
||||
if (isLoaded(UserIdentifier.of(u, null))) {
|
||||
CountDownLatch latch;
|
||||
|
||||
loadingLock.lock();
|
||||
try {
|
||||
boolean loaded = isLoaded(UserIdentifier.of(u, null));
|
||||
boolean locked = loadingLatches.containsKey(u);
|
||||
|
||||
if (loaded && !locked) {
|
||||
return get(u).getSpongeData();
|
||||
} else {
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
// User isn't already loaded. hopefully this call is not on the main thread. :(
|
||||
//plugin.getLog().warn("User Subject '" + u + "' was requested, but is not loaded in memory. Loading them from storage now.");
|
||||
long startTime = System.currentTimeMillis();
|
||||
plugin.getStorage().loadUser(u, "null").join();
|
||||
SpongeUser user = get(u);
|
||||
|
||||
if (user == null) {
|
||||
plugin.getLog().severe("Error whilst loading user '" + u + "'.");
|
||||
return plugin.getService().getFallbackUserSubjects().get(u.toString());
|
||||
latch.countDown();
|
||||
return;
|
||||
}
|
||||
|
||||
user.setupData(false);
|
||||
//plugin.getLog().warn("Loading '" + u + "' took " + (System.currentTimeMillis() - startTime) + " ms.");
|
||||
return user.getSpongeData();
|
||||
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();
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
if (user.getUserData() == null) {
|
||||
plugin.getLog().warn("User data not present for requested user id: " + id);
|
||||
}
|
||||
|
||||
return user.getSpongeData();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user