Remove the isAcceptingLogins storage state in favour of just throwing exceptions on usage

This commit is contained in:
Luck 2017-12-09 19:02:23 +00:00
parent 94b4e3d366
commit 9dd4f71526
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
15 changed files with 82 additions and 105 deletions

View File

@ -29,6 +29,8 @@ import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import me.lucko.luckperms.common.plugin.SchedulerAdapter;
import org.bukkit.scheduler.BukkitTask;
@ -37,7 +39,8 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class BukkitSchedulerAdapter implements SchedulerAdapter {
@ -69,7 +72,7 @@ public class BukkitSchedulerAdapter implements SchedulerAdapter {
this.plugin = plugin;
this.sync = new SyncExecutor();
this.asyncFallback = Executors.newCachedThreadPool();
this.asyncFallback = new FallbackAsyncExecutor();
this.asyncBukkit = new BukkitAsyncExecutor();
this.async = new AsyncExecutor();
}
@ -144,4 +147,10 @@ public class BukkitSchedulerAdapter implements SchedulerAdapter {
}
}
private static final class FallbackAsyncExecutor extends ThreadPoolExecutor {
private FallbackAsyncExecutor() {
super(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>(), new ThreadFactoryBuilder().setNameFormat("luckperms-fallback-%d").build());
}
}
}

View File

@ -134,7 +134,6 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
private ContextManager<Player> contextManager;
private CalculatorFactory calculatorFactory;
private BufferedRequest<Void> updateTaskBuffer;
private boolean started = false;
private CountDownLatch enableLatch = new CountDownLatch(1);
private VerboseHandler verboseHandler;
private BukkitSenderFactory senderFactory;
@ -174,7 +173,6 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
try {
enable();
started = true;
} finally {
// count down the latch when onEnable has been called
// we don't care about the result here
@ -328,8 +326,6 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
// Switch back to the fallback executor, the bukkit one won't allow new tasks
scheduler.setUseFallback(true);
started = false;
defaultsProvider.close();
permissionVault.shutdown();
verboseHandler.shutdown();

View File

@ -64,7 +64,7 @@ public class BukkitConnectionListener implements Listener {
/* wait for the plugin to enable. because these events are fired async, they can be called before
the plugin has enabled. */
try {
plugin.getEnableLatch().await(30, TimeUnit.SECONDS);
plugin.getEnableLatch().await(60, TimeUnit.SECONDS);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
@ -73,21 +73,6 @@ public class BukkitConnectionListener implements Listener {
plugin.getLog().info("Processing pre-login for " + e.getUniqueId() + " - " + e.getName());
}
/* there was an issue connecting to the DB, performing file i/o, etc.
we don't let players join in this case, because it means they can connect to the server without their permissions data.
some server admins rely on negating perms to stop users from causing damage etc, so it's really important that
this data is loaded. */
if (!plugin.isStarted() || !plugin.getStorage().isAcceptingLogins()) {
// log that the user tried to login, but was denied at this stage.
deniedAsyncLogin.add(e.getUniqueId());
// actually deny the connection.
plugin.getLog().warn("Permissions storage is not loaded. Denying connection from: " + e.getUniqueId() + " - " + e.getName());
e.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, Message.LOADING_ERROR.asString(plugin.getLocaleManager()));
return;
}
plugin.getUniqueConnections().add(e.getUniqueId());
/* Actually process the login for the connection.
@ -103,9 +88,10 @@ public class BukkitConnectionListener implements Listener {
User user = LoginHelper.loadUser(plugin, e.getUniqueId(), e.getName(), false);
plugin.getApiProvider().getEventFactory().handleUserLoginProcess(e.getUniqueId(), e.getName(), user);
} catch (Exception ex) {
plugin.getLog().severe("Exception occured whilst loading data for " + e.getUniqueId() + " - " + e.getName());
ex.printStackTrace();
// there was some error loading data. deny the connection
// deny the connection
deniedAsyncLogin.add(e.getUniqueId());
e.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, Message.LOADING_ERROR.asString(plugin.getLocaleManager()));
}

View File

@ -68,25 +68,6 @@ public class BungeeConnectionListener implements Listener {
plugin.getLog().info("Processing pre-login for " + c.getUniqueId() + " - " + c.getName());
}
/* there was an issue connecting to the DB, performing file i/o, etc.
as this is bungeecord, we will still allow the login, as players can't really do much harm without permissions data.
the proxy will just fallback to using the config file perms. */
if (!plugin.getStorage().isAcceptingLogins()) {
if (plugin.getConfiguration().get(ConfigKeys.CANCEL_FAILED_LOGINS)) {
// cancel the login attempt
e.setCancelReason(TextComponent.fromLegacyText(Message.LOADING_ERROR.asString(plugin.getLocaleManager())));
e.setCancelled(true);
} else {
// log that the user tried to login, but was denied at this stage.
plugin.getLog().warn("Permissions storage is not loaded. No permissions data will be loaded for: " + c.getUniqueId() + " - " + c.getName());
}
e.completeIntent(plugin);
return;
}
plugin.getScheduler().doAsync(() -> {
plugin.getUniqueConnections().add(c.getUniqueId());
@ -103,6 +84,7 @@ public class BungeeConnectionListener implements Listener {
User user = LoginHelper.loadUser(plugin, c.getUniqueId(), c.getName(), true);
plugin.getApiProvider().getEventFactory().handleUserLoginProcess(c.getUniqueId(), c.getName(), user);
} catch (Exception ex) {
plugin.getLog().severe("Exception occured whilst loading data for " + c.getUniqueId() + " - " + c.getName());
ex.printStackTrace();
// there was some error loading
@ -110,10 +92,7 @@ public class BungeeConnectionListener implements Listener {
// cancel the login attempt
e.setCancelReason(TextComponent.fromLegacyText(Message.LOADING_ERROR.asString(plugin.getLocaleManager())));
e.setCancelled(true);
} else {
plugin.getLog().warn("Error loading data. No permissions data will be loaded for: " + c.getUniqueId() + " - " + c.getName());
}
}
// finally, complete our intent to modify state, so the proxy can continue handling the connection.

View File

@ -61,7 +61,7 @@ public class ApiStorage implements Storage {
@Override
public boolean isAcceptingLogins() {
return handle.isAcceptingLogins();
return true;
}
@Override

View File

@ -28,7 +28,6 @@ package me.lucko.luckperms.common.storage;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.experimental.Delegate;
import me.lucko.luckperms.api.HeldPermission;
import me.lucko.luckperms.api.LogEntry;
@ -64,8 +63,6 @@ public class AbstractStorage implements Storage {
}
private final LuckPermsPlugin plugin;
@Delegate(types = Delegated.class)
private final AbstractDao dao;
@Getter
@ -81,11 +78,41 @@ public class AbstractStorage implements Storage {
return CompletableFuture.supplyAsync(supplier, dao.getPlugin().getScheduler().async());
}
@Override
public String getName() {
return dao.getName();
}
@Override
public Storage noBuffer() {
return this;
}
@Override
public void init() {
try {
dao.init();
} catch (Exception e) {
plugin.getLog().severe("Failed to init storage dao");
e.printStackTrace();
}
}
@Override
public void shutdown() {
try {
dao.shutdown();
} catch (Exception e) {
plugin.getLog().severe("Failed to shutdown storage dao");
e.printStackTrace();
}
}
@Override
public Map<String, String> getMeta() {
return dao.getMeta();
}
@Override
public CompletableFuture<Boolean> logAction(LogEntry entry) {
return makeFuture(() -> dao.logAction(entry));
@ -259,13 +286,4 @@ public class AbstractStorage implements Storage {
public CompletableFuture<String> getName(UUID uuid) {
return makeFuture(() -> dao.getName(uuid));
}
private interface Delegated {
String getName();
boolean isAcceptingLogins();
void setAcceptingLogins(boolean b);
void init();
void shutdown();
Map<String, String> getMeta();
}
}

View File

@ -51,10 +51,6 @@ public interface Storage {
String getName();
boolean isAcceptingLogins();
void setAcceptingLogins(boolean acceptingLogins);
Storage noBuffer();
void init();

View File

@ -28,7 +28,6 @@ package me.lucko.luckperms.common.storage.dao;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import me.lucko.luckperms.api.HeldPermission;
import me.lucko.luckperms.api.LogEntry;
@ -54,10 +53,6 @@ public abstract class AbstractDao {
@Getter
public final String name;
@Getter
@Setter
private boolean acceptingLogins = false;
public abstract void init();
public abstract void shutdown();

View File

@ -54,12 +54,18 @@ public class SplitStorageDao extends AbstractDao {
@Override
public void init() {
boolean success = true;
boolean failed = false;
for (AbstractDao ds : backing.values()) {
ds.init();
success = success && ds.isAcceptingLogins();
try {
ds.init();
} catch (Exception ex) {
failed = true;
ex.printStackTrace();
}
}
if (failed) {
throw new RuntimeException("One of the backing failed to init");
}
setAcceptingLogins(success);
}
@Override

View File

@ -192,8 +192,6 @@ public abstract class ConfigurateDao extends AbstractDao {
} catch (Exception e) {
e.printStackTrace();
}
setAcceptingLogins(true);
}
private static void mkdir(File file) throws IOException {

View File

@ -117,7 +117,6 @@ public class MongoDao extends AbstractDao {
}
database = mongoClient.getDatabase(configuration.getDatabase());
setAcceptingLogins(true);
}
@Override

View File

@ -207,10 +207,9 @@ public class SqlDao extends AbstractDao {
}
}
setAcceptingLogins(true);
} catch (Exception e) {
e.printStackTrace();
plugin.getLog().severe("Error occurred whilst initialising the database.");
e.printStackTrace();
shutdown();
}
}

View File

@ -91,6 +91,10 @@ public abstract class HikariConnectionFactory extends AbstractConnectionFactory
// The drivers are really old in some of the older Spigot binaries, so Connection#isValid doesn't work.
config.setConnectionTestQuery("/* LuckPerms ping */ SELECT 1");
// don't perform any initial connection validation - we subsequently call #getConnection
// to setup the schema anyways
config.setInitializationFailTimeout(-1);
hikari = new HikariDataSource(config);
}

View File

@ -27,7 +27,6 @@ package me.lucko.luckperms.common.storage.wrappings;
import lombok.AccessLevel;
import lombok.RequiredArgsConstructor;
import lombok.experimental.Delegate;
import me.lucko.luckperms.api.HeldPermission;
import me.lucko.luckperms.api.LogEntry;
@ -59,16 +58,30 @@ public class PhasedStorage implements Storage {
return new PhasedStorage(storage);
}
@Delegate(types = Delegated.class)
private final Storage delegate;
private final Phaser phaser = new Phaser();
@Override
public ApiStorage getDelegate() {
return delegate.getDelegate();
}
@Override
public String getName() {
return delegate.getName();
}
@Override
public Storage noBuffer() {
return this;
}
@Override
public void init() {
delegate.init();
}
@Override
public void shutdown() {
// Wait for other threads to finish.
@ -81,6 +94,11 @@ public class PhasedStorage implements Storage {
delegate.shutdown();
}
@Override
public Map<String, String> getMeta() {
return delegate.getMeta();
}
@Override
public CompletableFuture<Boolean> logAction(LogEntry entry) {
phaser.register();
@ -290,13 +308,4 @@ public class PhasedStorage implements Storage {
phaser.arriveAndDeregister();
}
}
private interface Delegated {
ApiStorage getDelegate();
String getName();
boolean isAcceptingLogins();
void setAcceptingLogins(boolean b);
void init();
Map<String, String> getMeta();
}
}

View File

@ -67,24 +67,6 @@ public class SpongeConnectionListener {
plugin.getLog().info("Processing auth event for " + p.getUniqueId() + " - " + p.getName());
}
/* either the plugin hasn't finished starting yet, or there was an issue connecting to the DB, performing file i/o, etc.
we don't let players join in this case, because it means they can connect to the server without their permissions data.
some server admins rely on negating perms to stop users from causing damage etc, so it's really important that
this data is loaded. */
if (!plugin.getStorage().isAcceptingLogins()) {
// log that the user tried to login, but was denied at this stage.
deniedAsyncLogin.add(p.getUniqueId());
// actually deny the connection.
plugin.getLog().warn("Permissions storage is not loaded. Denying connection from: " + p.getUniqueId() + " - " + p.getName());
e.setCancelled(true);
e.setMessageCancelled(false);
//noinspection deprecation
e.setMessage(TextSerializers.LEGACY_FORMATTING_CODE.deserialize(Message.LOADING_ERROR.asString(plugin.getLocaleManager())));
return;
}
plugin.getUniqueConnections().add(p.getUniqueId());
/* Actually process the login for the connection.
@ -100,6 +82,7 @@ public class SpongeConnectionListener {
User user = LoginHelper.loadUser(plugin, p.getUniqueId(), username, false);
plugin.getApiProvider().getEventFactory().handleUserLoginProcess(p.getUniqueId(), username, user);
} catch (Exception ex) {
plugin.getLog().severe("Exception occured whilst loading data for " + p.getUniqueId() + " - " + p.getName());
ex.printStackTrace();
deniedAsyncLogin.add(p.getUniqueId());