Rewrite the way user instances are cleaned up and unloaded - towards #674

This commit is contained in:
Luck
2018-01-10 21:28:33 +00:00
Unverified
parent ea94bd8696
commit 3201d10bdd
36 changed files with 725 additions and 468 deletions
@@ -28,7 +28,10 @@ package me.lucko.luckperms.bukkit;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import me.lucko.luckperms.common.plugin.SchedulerAdapter;
import me.lucko.luckperms.common.plugin.SchedulerTask;
import me.lucko.luckperms.common.utils.SafeIterator;
import org.bukkit.scheduler.BukkitScheduler;
import org.bukkit.scheduler.BukkitTask;
import java.util.Set;
@@ -51,7 +54,7 @@ public class BukkitSchedulerAdapter implements SchedulerAdapter {
private boolean useFallback = true;
private final Set<BukkitTask> tasks = ConcurrentHashMap.newKeySet();
private final Set<SchedulerTask> tasks = ConcurrentHashMap.newKeySet();
public BukkitSchedulerAdapter(LPBukkitPlugin plugin) {
this.plugin = plugin;
@@ -62,6 +65,10 @@ public class BukkitSchedulerAdapter implements SchedulerAdapter {
this.async = new AsyncExecutor();
}
private BukkitScheduler scheduler() {
return this.plugin.getServer().getScheduler();
}
@Override
public void doAsync(Runnable runnable) {
async().execute(runnable);
@@ -73,30 +80,32 @@ public class BukkitSchedulerAdapter implements SchedulerAdapter {
}
@Override
public void asyncRepeating(Runnable runnable, long intervalTicks) {
BukkitTask task = this.plugin.getServer().getScheduler().runTaskTimerAsynchronously(this.plugin, runnable, intervalTicks, intervalTicks);
public SchedulerTask asyncRepeating(Runnable runnable, long intervalTicks) {
SchedulerTask task = new BukkitSchedulerTask(scheduler().runTaskTimerAsynchronously(this.plugin, runnable, intervalTicks, intervalTicks));
this.tasks.add(task);
return task;
}
@Override
public void syncRepeating(Runnable runnable, long intervalTicks) {
BukkitTask task = this.plugin.getServer().getScheduler().runTaskTimer(this.plugin, runnable, intervalTicks, intervalTicks);
public SchedulerTask syncRepeating(Runnable runnable, long intervalTicks) {
SchedulerTask task = new BukkitSchedulerTask(scheduler().runTaskTimer(this.plugin, runnable, intervalTicks, intervalTicks));
this.tasks.add(task);
return task;
}
@Override
public void asyncLater(Runnable runnable, long delayTicks) {
this.plugin.getServer().getScheduler().runTaskLaterAsynchronously(this.plugin, runnable, delayTicks);
public SchedulerTask asyncLater(Runnable runnable, long delayTicks) {
return new BukkitSchedulerTask(scheduler().runTaskLaterAsynchronously(this.plugin, runnable, delayTicks));
}
@Override
public void syncLater(Runnable runnable, long delayTicks) {
this.plugin.getServer().getScheduler().scheduleSyncDelayedTask(this.plugin, runnable, delayTicks);
public SchedulerTask syncLater(Runnable runnable, long delayTicks) {
return new BukkitSchedulerTask(scheduler().runTaskLater(this.plugin, runnable, delayTicks));
}
@Override
public void shutdown() {
this.tasks.forEach(BukkitTask::cancel);
SafeIterator.iterate(this.tasks, SchedulerTask::cancel);
// wait for executor
this.asyncFallback.shutdown();
@@ -161,4 +170,17 @@ public class BukkitSchedulerAdapter implements SchedulerAdapter {
}
}
private static final class BukkitSchedulerTask implements SchedulerTask {
private final BukkitTask task;
private BukkitSchedulerTask(BukkitTask task) {
this.task = task;
}
@Override
public void cancel() {
this.task.cancel();
}
}
}
@@ -63,12 +63,9 @@ import me.lucko.luckperms.common.locale.NoopLocaleManager;
import me.lucko.luckperms.common.locale.SimpleLocaleManager;
import me.lucko.luckperms.common.logging.Logger;
import me.lucko.luckperms.common.logging.SenderLogger;
import me.lucko.luckperms.common.managers.GenericGroupManager;
import me.lucko.luckperms.common.managers.GenericTrackManager;
import me.lucko.luckperms.common.managers.GenericUserManager;
import me.lucko.luckperms.common.managers.GroupManager;
import me.lucko.luckperms.common.managers.TrackManager;
import me.lucko.luckperms.common.managers.UserManager;
import me.lucko.luckperms.common.managers.group.StandardGroupManager;
import me.lucko.luckperms.common.managers.track.StandardTrackManager;
import me.lucko.luckperms.common.managers.user.StandardUserManager;
import me.lucko.luckperms.common.messaging.ExtendedMessagingService;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
@@ -80,7 +77,6 @@ import me.lucko.luckperms.common.tasks.CacheHousekeepingTask;
import me.lucko.luckperms.common.tasks.ExpireTemporaryTask;
import me.lucko.luckperms.common.tasks.UpdateTask;
import me.lucko.luckperms.common.treeview.PermissionVault;
import me.lucko.luckperms.common.utils.LoginHelper;
import me.lucko.luckperms.common.utils.UuidCache;
import me.lucko.luckperms.common.verbose.VerboseHandler;
@@ -115,9 +111,9 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
private BukkitCommandExecutor commandManager;
private VaultHookManager vaultHookManager = null;
private LuckPermsConfiguration configuration;
private UserManager userManager;
private GroupManager groupManager;
private TrackManager trackManager;
private StandardUserManager userManager;
private StandardGroupManager groupManager;
private StandardTrackManager trackManager;
private Storage storage;
private FileWatcher fileWatcher = null;
private ExtendedMessagingService messagingService = null;
@@ -205,7 +201,8 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
this.scheduler.syncLater(new BukkitProcessorsSetupTask(this), 1L);
// register events
getServer().getPluginManager().registerEvents(new BukkitConnectionListener(this), this);
BukkitConnectionListener connectionListener = new BukkitConnectionListener(this);
getServer().getPluginManager().registerEvents(connectionListener, this);
getServer().getPluginManager().registerEvents(new BukkitPlatformListener(this), this);
if (getConfiguration().get(ConfigKeys.WATCH_FILES)) {
@@ -237,9 +234,9 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
// load internal managers
getLog().info("Loading internal permission managers...");
this.uuidCache = new UuidCache(this);
this.userManager = new GenericUserManager(this);
this.groupManager = new GenericGroupManager(this);
this.trackManager = new GenericTrackManager(this);
this.userManager = new StandardUserManager(this);
this.groupManager = new StandardGroupManager(this);
this.trackManager = new StandardTrackManager(this);
this.calculatorFactory = new BukkitCalculatorFactory(this);
this.cachedStateManager = new CachedStateManager();
@@ -312,7 +309,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
for (Player player : getServer().getOnlinePlayers()) {
this.scheduler.doAsync(() -> {
try {
LoginHelper.loadUser(this, player.getUniqueId(), player.getName(), false);
connectionListener.loadUser(player.getUniqueId(), player.getName());
User user = getUserManager().getIfLoaded(getUuidCache().getUUID(player.getUniqueId()));
if (user != null) {
this.scheduler.doSync(() -> {
@@ -584,17 +581,17 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
}
@Override
public UserManager getUserManager() {
public StandardUserManager getUserManager() {
return this.userManager;
}
@Override
public GroupManager getGroupManager() {
public StandardGroupManager getGroupManager() {
return this.groupManager;
}
@Override
public TrackManager getTrackManager() {
public StandardTrackManager getTrackManager() {
return this.trackManager;
}
@@ -31,7 +31,7 @@ import me.lucko.luckperms.bukkit.model.PermissibleInjector;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.locale.Message;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.utils.LoginHelper;
import me.lucko.luckperms.common.utils.AbstractLoginListener;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@@ -47,13 +47,14 @@ import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
public class BukkitConnectionListener implements Listener {
public class BukkitConnectionListener extends AbstractLoginListener implements Listener {
private final LPBukkitPlugin plugin;
private final Set<UUID> deniedAsyncLogin = Collections.synchronizedSet(new HashSet<>());
private final Set<UUID> deniedLogin = Collections.synchronizedSet(new HashSet<>());
public BukkitConnectionListener(LPBukkitPlugin plugin) {
super(plugin);
this.plugin = plugin;
}
@@ -86,7 +87,7 @@ public class BukkitConnectionListener implements Listener {
- creating a user instance in the UserManager for this connection.
- setting up cached data. */
try {
User user = LoginHelper.loadUser(this.plugin, e.getUniqueId(), e.getName(), false);
User user = loadUser(e.getUniqueId(), e.getName());
this.plugin.getEventFactory().handleUserLoginProcess(e.getUniqueId(), e.getName(), user);
} catch (Exception ex) {
this.plugin.getLog().severe("Exception occured whilst loading data for " + e.getUniqueId() + " - " + e.getName());
@@ -115,12 +116,6 @@ public class BukkitConnectionListener implements Listener {
return;
}
// Login event was cancelled by another plugin, but it wasn't cancelled when we handled it at LOW
if (e.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) {
// Schedule cleanup of this user.
this.plugin.getUserManager().scheduleUnload(e.getUniqueId());
}
}
@EventHandler(priority = EventPriority.LOWEST)
@@ -180,8 +175,6 @@ public class BukkitConnectionListener implements Listener {
// Login event was cancelled by another plugin since we first loaded their data
if (denied || e.getResult() != PlayerLoginEvent.Result.ALLOWED) {
// Schedule cleanup of this user.
this.plugin.getUserManager().scheduleUnload(e.getPlayer().getUniqueId());
return;
}
@@ -206,8 +199,9 @@ public class BukkitConnectionListener implements Listener {
player.setOp(false);
}
// Request that the users data is unloaded.
this.plugin.getUserManager().scheduleUnload(player.getUniqueId());
// Register with the housekeeper, so the User's instance will stick
// around for a bit after they disconnect
this.plugin.getUserManager().getHouseKeeper().registerUsage(player.getUniqueId());
}
}