Rewrite the way user instances are cleaned up and unloaded - towards #674
This commit is contained in:
@@ -26,8 +26,11 @@
|
||||
package me.lucko.luckperms.bungee;
|
||||
|
||||
import me.lucko.luckperms.common.plugin.SchedulerAdapter;
|
||||
import me.lucko.luckperms.common.plugin.SchedulerTask;
|
||||
import me.lucko.luckperms.common.utils.SafeIterator;
|
||||
|
||||
import net.md_5.bungee.api.scheduler.ScheduledTask;
|
||||
import net.md_5.bungee.api.scheduler.TaskScheduler;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@@ -35,16 +38,32 @@ import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class BungeeSchedulerAdapter implements SchedulerAdapter {
|
||||
|
||||
// the number of ticks which occur in a second - this is a server implementation detail
|
||||
public static final int TICKS_PER_SECOND = 20;
|
||||
// the number of milliseconds in a second - constant
|
||||
public static final int MILLISECONDS_PER_SECOND = 1000;
|
||||
// the number of milliseconds in a tick - assuming the server runs at a perfect tick rate
|
||||
public static final int MILLISECONDS_PER_TICK = MILLISECONDS_PER_SECOND / TICKS_PER_SECOND;
|
||||
|
||||
private static long ticksToMillis(long ticks) {
|
||||
return ticks * MILLISECONDS_PER_TICK;
|
||||
}
|
||||
|
||||
private final LPBungeePlugin plugin;
|
||||
|
||||
private final Executor asyncExecutor;
|
||||
private final Set<ScheduledTask> tasks = ConcurrentHashMap.newKeySet();
|
||||
private final Set<SchedulerTask> tasks = ConcurrentHashMap.newKeySet();
|
||||
|
||||
public BungeeSchedulerAdapter(LPBungeePlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.asyncExecutor = r -> plugin.getProxy().getScheduler().runAsync(plugin, r);
|
||||
}
|
||||
|
||||
private TaskScheduler scheduler() {
|
||||
return this.plugin.getProxy().getScheduler();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Executor async() {
|
||||
return this.asyncExecutor;
|
||||
@@ -66,30 +85,44 @@ public class BungeeSchedulerAdapter implements SchedulerAdapter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void asyncRepeating(Runnable runnable, long intervalTicks) {
|
||||
long millis = intervalTicks * 50L; // convert from ticks to milliseconds
|
||||
ScheduledTask task = this.plugin.getProxy().getScheduler().schedule(this.plugin, runnable, millis, millis, TimeUnit.MILLISECONDS);
|
||||
public SchedulerTask asyncRepeating(Runnable runnable, long intervalTicks) {
|
||||
long millis = ticksToMillis(intervalTicks);
|
||||
SchedulerTask task = new BungeeSchedulerTask(scheduler().schedule(this.plugin, runnable, millis, millis, TimeUnit.MILLISECONDS));
|
||||
this.tasks.add(task);
|
||||
return task;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syncRepeating(Runnable runnable, long intervalTicks) {
|
||||
asyncRepeating(runnable, intervalTicks);
|
||||
public SchedulerTask syncRepeating(Runnable runnable, long intervalTicks) {
|
||||
return asyncRepeating(runnable, intervalTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void asyncLater(Runnable runnable, long delayTicks) {
|
||||
long millis = delayTicks * 50L; // convert from ticks to milliseconds
|
||||
this.plugin.getProxy().getScheduler().schedule(this.plugin, runnable, millis, TimeUnit.MILLISECONDS);
|
||||
public SchedulerTask asyncLater(Runnable runnable, long delayTicks) {
|
||||
return new BungeeSchedulerTask(scheduler().schedule(this.plugin, runnable, ticksToMillis(delayTicks), TimeUnit.MILLISECONDS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void syncLater(Runnable runnable, long delayTicks) {
|
||||
asyncLater(runnable, delayTicks);
|
||||
public SchedulerTask syncLater(Runnable runnable, long delayTicks) {
|
||||
return asyncLater(runnable, delayTicks);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown() {
|
||||
this.tasks.forEach(ScheduledTask::cancel);
|
||||
SafeIterator.iterate(this.tasks, SchedulerTask::cancel);
|
||||
}
|
||||
|
||||
private static final class BungeeSchedulerTask implements SchedulerTask {
|
||||
private final ScheduledTask task;
|
||||
|
||||
private BungeeSchedulerTask(ScheduledTask task) {
|
||||
this.task = task;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
this.task.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -57,12 +57,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;
|
||||
@@ -101,9 +98,9 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
|
||||
private SchedulerAdapter scheduler;
|
||||
private CommandManager commandManager;
|
||||
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;
|
||||
@@ -183,9 +180,9 @@ public class LPBungeePlugin extends Plugin 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 BungeeCalculatorFactory(this);
|
||||
this.cachedStateManager = new CachedStateManager();
|
||||
|
||||
@@ -394,17 +391,17 @@ public class LPBungeePlugin extends Plugin 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;
|
||||
}
|
||||
|
||||
|
||||
+7
-9
@@ -29,7 +29,7 @@ import me.lucko.luckperms.bungee.LPBungeePlugin;
|
||||
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 net.md_5.bungee.api.chat.TextComponent;
|
||||
import net.md_5.bungee.api.connection.PendingConnection;
|
||||
@@ -43,10 +43,11 @@ import net.md_5.bungee.event.EventPriority;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class BungeeConnectionListener implements Listener {
|
||||
public class BungeeConnectionListener extends AbstractLoginListener implements Listener {
|
||||
private final LPBungeePlugin plugin;
|
||||
|
||||
public BungeeConnectionListener(LPBungeePlugin plugin) {
|
||||
super(plugin);
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@@ -82,7 +83,7 @@ public class BungeeConnectionListener implements Listener {
|
||||
- creating a user instance in the UserManager for this connection.
|
||||
- setting up cached data. */
|
||||
try {
|
||||
User user = LoginHelper.loadUser(this.plugin, c.getUniqueId(), c.getName(), true);
|
||||
User user = loadUser(c.getUniqueId(), c.getName());
|
||||
this.plugin.getEventFactory().handleUserLoginProcess(c.getUniqueId(), c.getName(), user);
|
||||
} catch (Exception ex) {
|
||||
this.plugin.getLog().severe("Exception occured whilst loading data for " + c.getUniqueId() + " - " + c.getName());
|
||||
@@ -98,10 +99,6 @@ public class BungeeConnectionListener implements Listener {
|
||||
|
||||
// finally, complete our intent to modify state, so the proxy can continue handling the connection.
|
||||
e.completeIntent(this.plugin);
|
||||
|
||||
// schedule a cleanup of the users data in a few seconds.
|
||||
// this should cover the eventuality that the login fails.
|
||||
this.plugin.getUserManager().scheduleUnload(c.getUniqueId());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -135,8 +132,9 @@ public class BungeeConnectionListener implements Listener {
|
||||
// Wait until the last priority to unload, so plugins can still perform permission checks on this event
|
||||
@EventHandler(priority = EventPriority.HIGHEST)
|
||||
public void onPlayerQuit(PlayerDisconnectEvent e) {
|
||||
// Request that the users data is unloaded.
|
||||
this.plugin.getUserManager().scheduleUnload(e.getPlayer().getUniqueId());
|
||||
// Register with the housekeeper, so the User's instance will stick
|
||||
// around for a bit after they disconnect
|
||||
this.plugin.getUserManager().getHouseKeeper().registerUsage(e.getPlayer().getUniqueId());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user