Run all commands on the same thread - fixes #79

This commit is contained in:
Luck 2016-12-11 11:34:18 +00:00
parent 167489823a
commit 70aa3964ee
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
12 changed files with 18 additions and 190 deletions

View File

@ -50,8 +50,7 @@ class BukkitCommand extends CommandManager implements CommandExecutor, TabExecut
onCommand( onCommand(
plugin.getSenderFactory().wrap(sender), plugin.getSenderFactory().wrap(sender),
label, label,
Util.stripQuotes(Splitter.on(Patterns.COMMAND_SEPARATOR).omitEmptyStrings().splitToList(Joiner.on(' ').join(args))), Util.stripQuotes(Splitter.on(Patterns.COMMAND_SEPARATOR).omitEmptyStrings().splitToList(Joiner.on(' ').join(args)))
null
); );
return true; return true;
} }

View File

@ -41,7 +41,6 @@ import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.api.ApiProvider; import me.lucko.luckperms.common.api.ApiProvider;
import me.lucko.luckperms.common.caching.handlers.CachedStateManager; import me.lucko.luckperms.common.caching.handlers.CachedStateManager;
import me.lucko.luckperms.common.calculators.CalculatorFactory; import me.lucko.luckperms.common.calculators.CalculatorFactory;
import me.lucko.luckperms.common.commands.ConsecutiveExecutor;
import me.lucko.luckperms.common.commands.sender.Sender; import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.config.LPConfiguration; import me.lucko.luckperms.common.config.LPConfiguration;
import me.lucko.luckperms.common.constants.Permission; import me.lucko.luckperms.common.constants.Permission;
@ -104,7 +103,6 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
private ApiProvider apiProvider; private ApiProvider apiProvider;
private Logger log; private Logger log;
private Importer importer; private Importer importer;
private ConsecutiveExecutor consecutiveExecutor;
private DefaultsProvider defaultsProvider; private DefaultsProvider defaultsProvider;
private ChildPermissionProvider childPermissionProvider; private ChildPermissionProvider childPermissionProvider;
private LocaleManager localeManager; private LocaleManager localeManager;
@ -218,7 +216,6 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
groupManager = new GenericGroupManager(this); groupManager = new GenericGroupManager(this);
trackManager = new GenericTrackManager(); trackManager = new GenericTrackManager();
importer = new Importer(commandManager); importer = new Importer(commandManager);
consecutiveExecutor = new ConsecutiveExecutor(commandManager);
calculatorFactory = new BukkitCalculatorFactory(this); calculatorFactory = new BukkitCalculatorFactory(this);
cachedStateManager = new CachedStateManager(this); cachedStateManager = new CachedStateManager(this);
@ -255,7 +252,6 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
// register tasks // register tasks
getServer().getScheduler().runTaskTimerAsynchronously(this, new ExpireTemporaryTask(this), 60L, 60L); getServer().getScheduler().runTaskTimerAsynchronously(this, new ExpireTemporaryTask(this), 60L, 60L);
getServer().getScheduler().runTaskTimerAsynchronously(this, consecutiveExecutor, 20L, 20L);
// register permissions // register permissions
registerPermissions(getConfiguration().isCommandsAllowOp() ? PermissionDefault.OP : PermissionDefault.FALSE); registerPermissions(getConfiguration().isCommandsAllowOp() ? PermissionDefault.OP : PermissionDefault.FALSE);

View File

@ -50,8 +50,7 @@ class BungeeCommand extends Command implements TabExecutor {
manager.onCommand( manager.onCommand(
plugin.getSenderFactory().wrap(sender), plugin.getSenderFactory().wrap(sender),
"bperms", "bperms",
Util.stripQuotes(Splitter.on(Patterns.COMMAND_SEPARATOR).omitEmptyStrings().splitToList(Joiner.on(' ').join(args))), Util.stripQuotes(Splitter.on(Patterns.COMMAND_SEPARATOR).omitEmptyStrings().splitToList(Joiner.on(' ').join(args)))
null
); );
} }

View File

@ -35,7 +35,6 @@ import me.lucko.luckperms.common.api.ApiProvider;
import me.lucko.luckperms.common.caching.handlers.CachedStateManager; import me.lucko.luckperms.common.caching.handlers.CachedStateManager;
import me.lucko.luckperms.common.calculators.CalculatorFactory; import me.lucko.luckperms.common.calculators.CalculatorFactory;
import me.lucko.luckperms.common.commands.CommandManager; import me.lucko.luckperms.common.commands.CommandManager;
import me.lucko.luckperms.common.commands.ConsecutiveExecutor;
import me.lucko.luckperms.common.commands.sender.Sender; import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.config.LPConfiguration; import me.lucko.luckperms.common.config.LPConfiguration;
import me.lucko.luckperms.common.contexts.ContextManager; import me.lucko.luckperms.common.contexts.ContextManager;
@ -88,7 +87,6 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
private ApiProvider apiProvider; private ApiProvider apiProvider;
private Logger log; private Logger log;
private Importer importer; private Importer importer;
private ConsecutiveExecutor consecutiveExecutor;
private LocaleManager localeManager; private LocaleManager localeManager;
private CachedStateManager cachedStateManager; private CachedStateManager cachedStateManager;
private ContextManager<ProxiedPlayer> contextManager; private ContextManager<ProxiedPlayer> contextManager;
@ -164,7 +162,6 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
groupManager = new GenericGroupManager(this); groupManager = new GenericGroupManager(this);
trackManager = new GenericTrackManager(); trackManager = new GenericTrackManager();
importer = new Importer(commandManager); importer = new Importer(commandManager);
consecutiveExecutor = new ConsecutiveExecutor(commandManager);
calculatorFactory = new BungeeCalculatorFactory(this); calculatorFactory = new BungeeCalculatorFactory(this);
cachedStateManager = new CachedStateManager(this); cachedStateManager = new CachedStateManager(this);
@ -190,7 +187,6 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
// register tasks // register tasks
getProxy().getScheduler().schedule(this, new ExpireTemporaryTask(this), 3L, 3L, TimeUnit.SECONDS); getProxy().getScheduler().schedule(this, new ExpireTemporaryTask(this), 3L, 3L, TimeUnit.SECONDS);
getProxy().getScheduler().schedule(this, consecutiveExecutor, 1L, 1L, TimeUnit.SECONDS);
getLog().info("Successfully loaded."); getLog().info("Successfully loaded.");
} }

View File

@ -29,7 +29,6 @@ import me.lucko.luckperms.common.api.ApiProvider;
import me.lucko.luckperms.common.caching.handlers.CachedStateManager; import me.lucko.luckperms.common.caching.handlers.CachedStateManager;
import me.lucko.luckperms.common.calculators.CalculatorFactory; import me.lucko.luckperms.common.calculators.CalculatorFactory;
import me.lucko.luckperms.common.commands.BaseCommand; import me.lucko.luckperms.common.commands.BaseCommand;
import me.lucko.luckperms.common.commands.ConsecutiveExecutor;
import me.lucko.luckperms.common.commands.sender.Sender; import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.config.LPConfiguration; import me.lucko.luckperms.common.config.LPConfiguration;
import me.lucko.luckperms.common.constants.Message; import me.lucko.luckperms.common.constants.Message;
@ -132,13 +131,6 @@ public interface LuckPermsPlugin {
*/ */
Importer getImporter(); Importer getImporter();
/**
* Gets the consecutive command executor instance
*
* @return the consecutive executor
*/
ConsecutiveExecutor getConsecutiveExecutor();
/** /**
* Gets the instance providing locale translations for the plugin * Gets the instance providing locale translations for the plugin
* *

View File

@ -37,7 +37,6 @@ import me.lucko.luckperms.common.commands.misc.ExportCommand;
import me.lucko.luckperms.common.commands.misc.ImportCommand; import me.lucko.luckperms.common.commands.misc.ImportCommand;
import me.lucko.luckperms.common.commands.misc.InfoCommand; import me.lucko.luckperms.common.commands.misc.InfoCommand;
import me.lucko.luckperms.common.commands.misc.NetworkSyncCommand; import me.lucko.luckperms.common.commands.misc.NetworkSyncCommand;
import me.lucko.luckperms.common.commands.misc.QueueCommand;
import me.lucko.luckperms.common.commands.misc.SyncCommand; import me.lucko.luckperms.common.commands.misc.SyncCommand;
import me.lucko.luckperms.common.commands.misc.VerboseCommand; import me.lucko.luckperms.common.commands.misc.VerboseCommand;
import me.lucko.luckperms.common.commands.sender.Sender; import me.lucko.luckperms.common.commands.sender.Sender;
@ -59,18 +58,24 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.function.Consumer; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class CommandManager { public class CommandManager {
@Getter @Getter
private final LuckPermsPlugin plugin; private final LuckPermsPlugin plugin;
private final ExecutorService executor;
@Getter @Getter
private final List<BaseCommand> mainCommands; private final List<BaseCommand> mainCommands;
public CommandManager(LuckPermsPlugin plugin) { public CommandManager(LuckPermsPlugin plugin) {
this.plugin = plugin; this.plugin = plugin;
this.executor = Executors.newSingleThreadExecutor();
ImmutableList.Builder<BaseCommand> l = ImmutableList.builder(); ImmutableList.Builder<BaseCommand> l = ImmutableList.builder();
l.add(new UserMainCommand()) l.add(new UserMainCommand())
@ -84,7 +89,6 @@ public class CommandManager {
.add(new VerboseCommand()) .add(new VerboseCommand())
.add(new ImportCommand()) .add(new ImportCommand())
.add(new ExportCommand()) .add(new ExportCommand())
.add(new QueueCommand())
.add(new MigrationMainCommand()) .add(new MigrationMainCommand())
.add(new UsersBulkEditMainCommand()) .add(new UsersBulkEditMainCommand())
.add(new CreateGroup()) .add(new CreateGroup())
@ -100,31 +104,16 @@ public class CommandManager {
/** /**
* Generic on command method to be called from the command executor object of the platform * Generic on command method to be called from the command executor object of the platform
* Unlike {@link #onCommand(Sender, String, List)}, this method is called in a new thread * Unlike {@link #onCommand(Sender, String, List)}, this method is called in a new thread
*
* @param sender who sent the command * @param sender who sent the command
* @param label the command label used * @param label the command label used
* @param args the arguments provided * @param args the arguments provided
* @param result the callback to be called when the command has fully executed
*/ */
public void onCommand(Sender sender, String label, List<String> args, Consumer<CommandResult> result) { public Future<CommandResult> onCommand(Sender sender, String label, List<String> args) {
plugin.doAsync(() -> { return executor.submit(() -> execute(sender, label, args));
CommandResult r = onCommand(sender, label, args);
if (result != null) {
plugin.doSync(() -> result.accept(r));
}
});
} }
/**
* Generic on command method to be called from the command executor object of the platform
*
* @param sender who sent the command
* @param label the command label used
* @param args the arguments provided
* @return if the command was successful
*/
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public CommandResult onCommand(Sender sender, String label, List<String> args) { private CommandResult execute(Sender sender, String label, List<String> args) {
// Handle no arguments // Handle no arguments
if (args.size() == 0) { if (args.size() == 0) {
sendCommandUsage(sender, label); sendCommandUsage(sender, label);

View File

@ -1,74 +0,0 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.common.commands.sender.Sender;
import java.util.ArrayList;
import java.util.List;
/**
* Executes commands consecutively
*/
@RequiredArgsConstructor
public class ConsecutiveExecutor implements Runnable {
private final CommandManager manager;
private final List<QueuedCommand> commands = new ArrayList<>();
public void queueCommand(QueuedCommand command) {
synchronized (commands) {
commands.add(command);
}
}
@Override
public void run() {
final List<QueuedCommand> toExecute = new ArrayList<>();
synchronized (commands) {
toExecute.addAll(commands);
commands.clear();
}
if (toExecute.isEmpty()) {
return;
}
for (QueuedCommand command : toExecute) {
manager.onCommand(command.getSender(), "perms", command.getArgs());
}
}
@Getter
@AllArgsConstructor
public static class QueuedCommand {
private final Sender sender;
private final List<String> args;
}
}

View File

@ -1,61 +0,0 @@
/*
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package me.lucko.luckperms.common.commands.misc;
import me.lucko.luckperms.common.LuckPermsPlugin;
import me.lucko.luckperms.common.commands.Arg;
import me.lucko.luckperms.common.commands.CommandResult;
import me.lucko.luckperms.common.commands.ConsecutiveExecutor;
import me.lucko.luckperms.common.commands.SingleCommand;
import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.constants.Constants;
import me.lucko.luckperms.common.constants.Permission;
import me.lucko.luckperms.common.utils.Predicates;
import java.util.List;
public class QueueCommand extends SingleCommand {
public QueueCommand() {
super("QueueCommand", "Queue a command for execution", "/%s queuecommand <command args...>", Permission.MIGRATION, Predicates.not(1),
Arg.list(
Arg.create("command args...", true, "the command's arguments")
)
);
}
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, List<String> args, String label) {
if (args.get(0).equalsIgnoreCase(getName())) {
// Prevent infinite loops
return CommandResult.FAILURE;
}
plugin.getConsecutiveExecutor().queueCommand(new ConsecutiveExecutor.QueuedCommand(sender, args));
return CommandResult.SUCCESS;
}
@Override
public boolean isAuthorized(Sender sender) {
return sender.getUuid().equals(Constants.getConsoleUUID());
}
}

View File

@ -107,7 +107,7 @@ public class Importer {
executing = index; executing = index;
try { try {
CommandResult result = commandManager.onCommand(fake, "perms", Splitter.on(' ').splitToList(command)); CommandResult result = commandManager.onCommand(fake, "perms", Splitter.on(' ').splitToList(command)).get();
getResult(index, command).setResult(result); getResult(index, command).setResult(result);
} catch (Exception e) { } catch (Exception e) {

View File

@ -51,13 +51,10 @@ import java.util.UUID;
import static me.lucko.luckperms.common.core.model.PermissionHolder.exportToLegacy; import static me.lucko.luckperms.common.core.model.PermissionHolder.exportToLegacy;
abstract class SQLBacking extends AbstractBacking { abstract class SQLBacking extends AbstractBacking {
private static final QueryPS EMPTY_PS = preparedStatement -> { private static final QueryPS EMPTY_PS = preparedStatement -> {};
};
private static final Type NM_TYPE = new TypeToken<Map<String, Boolean>>() { private static final Type NM_TYPE = new TypeToken<Map<String, Boolean>>() {}.getType();
}.getType(); private static final Type T_TYPE = new TypeToken<List<String>>() {}.getType();
private static final Type T_TYPE = new TypeToken<List<String>>() {
}.getType();
private static final String USER_INSERT = "INSERT INTO lp_users VALUES(?, ?, ?, ?)"; private static final String USER_INSERT = "INSERT INTO lp_users VALUES(?, ?, ?, ?)";
private static final String USER_SELECT = "SELECT * FROM lp_users WHERE uuid=?"; private static final String USER_SELECT = "SELECT * FROM lp_users WHERE uuid=?";

View File

@ -35,7 +35,6 @@ import me.lucko.luckperms.common.api.ApiProvider;
import me.lucko.luckperms.common.caching.handlers.CachedStateManager; import me.lucko.luckperms.common.caching.handlers.CachedStateManager;
import me.lucko.luckperms.common.calculators.CalculatorFactory; import me.lucko.luckperms.common.calculators.CalculatorFactory;
import me.lucko.luckperms.common.commands.BaseCommand; import me.lucko.luckperms.common.commands.BaseCommand;
import me.lucko.luckperms.common.commands.ConsecutiveExecutor;
import me.lucko.luckperms.common.commands.sender.Sender; import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.config.LPConfiguration; import me.lucko.luckperms.common.config.LPConfiguration;
import me.lucko.luckperms.common.constants.Permission; import me.lucko.luckperms.common.constants.Permission;
@ -139,7 +138,6 @@ public class LPSpongePlugin implements LuckPermsPlugin {
private ApiProvider apiProvider; private ApiProvider apiProvider;
private me.lucko.luckperms.api.Logger log; private me.lucko.luckperms.api.Logger log;
private Importer importer; private Importer importer;
private ConsecutiveExecutor consecutiveExecutor;
private LuckPermsService service; private LuckPermsService service;
private LocaleManager localeManager; private LocaleManager localeManager;
private CachedStateManager cachedStateManager; private CachedStateManager cachedStateManager;
@ -215,7 +213,6 @@ public class LPSpongePlugin implements LuckPermsPlugin {
groupManager = new SpongeGroupManager(this); groupManager = new SpongeGroupManager(this);
trackManager = new GenericTrackManager(); trackManager = new GenericTrackManager();
importer = new Importer(commandManager); importer = new Importer(commandManager);
consecutiveExecutor = new ConsecutiveExecutor(commandManager);
calculatorFactory = new SpongeCalculatorFactory(this); calculatorFactory = new SpongeCalculatorFactory(this);
cachedStateManager = new CachedStateManager(this); cachedStateManager = new CachedStateManager(this);
@ -253,7 +250,6 @@ public class LPSpongePlugin implements LuckPermsPlugin {
// register tasks // register tasks
scheduler.createTaskBuilder().async().intervalTicks(60L).execute(new ExpireTemporaryTask(this)).submit(this); scheduler.createTaskBuilder().async().intervalTicks(60L).execute(new ExpireTemporaryTask(this)).submit(this);
scheduler.createTaskBuilder().async().intervalTicks(20L).execute(consecutiveExecutor).submit(this);
getLog().info("Successfully loaded."); getLog().info("Successfully loaded.");
} }

View File

@ -59,8 +59,7 @@ class SpongeCommand extends CommandManager implements CommandCallable {
onCommand( onCommand(
plugin.getSenderFactory().wrap(source), plugin.getSenderFactory().wrap(source),
"perms", "perms",
Util.stripQuotes(Splitter.on(Patterns.COMMAND_SEPARATOR).omitEmptyStrings().splitToList(s)), Util.stripQuotes(Splitter.on(Patterns.COMMAND_SEPARATOR).omitEmptyStrings().splitToList(s))
null
); );
return CommandResult.success(); return CommandResult.success();
} }