13
0
geforkt von Mirrors/Velocity

Wait for player disconnect events on shutdown. (#229)

Dieser Commit ist enthalten in:
Seppe Volkaerts 2019-07-05 05:49:40 +02:00 committet von Andrew Steinborn
Ursprung 5b518eaf20
Commit 145dfa8ac6
2 geänderte Dateien mit 38 neuen und 5 gelöschten Zeilen

Datei anzeigen

@ -59,9 +59,14 @@ import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.IntFunction;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import net.kyori.text.Component; import net.kyori.text.Component;
import net.kyori.text.TextComponent; import net.kyori.text.TextComponent;
@ -379,14 +384,35 @@ public class VelocityServer implements ProxyServer {
Runnable shutdownProcess = () -> { Runnable shutdownProcess = () -> {
logger.info("Shutting down the proxy..."); logger.info("Shutting down the proxy...");
for (ConnectedPlayer player : ImmutableList.copyOf(connectionsByUuid.values())) { // Shutdown the connection manager, this should be
// done first to refuse new connections
cm.shutdown();
ImmutableList<ConnectedPlayer> players = ImmutableList.copyOf(connectionsByUuid.values());
for (ConnectedPlayer player : players) {
player.disconnect(TextComponent.of("Proxy shutting down.")); player.disconnect(TextComponent.of("Proxy shutting down."));
} }
this.cm.shutdown(); try {
boolean timedOut = false;
try { try {
if (!eventManager.shutdown() || !scheduler.shutdown()) { // Wait for the connections finish tearing down, this
// makes sure that all the disconnect events are being fired
CompletableFuture<Void> playersTeardownFuture = CompletableFuture.allOf(players.stream()
.map(ConnectedPlayer::getTeardownFuture)
.toArray((IntFunction<CompletableFuture<Void>[]>) CompletableFuture[]::new));
playersTeardownFuture.get(10, TimeUnit.SECONDS);
} catch (TimeoutException | ExecutionException e) {
timedOut = true;
}
timedOut = !eventManager.shutdown() || timedOut;
timedOut = !scheduler.shutdown() || timedOut;
if (timedOut) {
logger.error("Your plugins took over 10 seconds to shut down."); logger.error("Your plugins took over 10 seconds to shut down.");
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {

Datei anzeigen

@ -57,6 +57,7 @@ import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException; import java.util.concurrent.CompletionException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import net.kyori.text.Component; import net.kyori.text.Component;
import net.kyori.text.TextComponent; import net.kyori.text.TextComponent;
@ -96,6 +97,7 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
private final VelocityServer server; private final VelocityServer server;
private ClientConnectionPhase connectionPhase; private ClientConnectionPhase connectionPhase;
private final Collection<String> knownChannels; private final Collection<String> knownChannels;
private final CompletableFuture<Void> teardownFuture = new CompletableFuture<>();
private @MonotonicNonNull List<String> serversToTry = null; private @MonotonicNonNull List<String> serversToTry = null;
@ -553,7 +555,12 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
connectedServer.disconnect(); connectedServer.disconnect();
} }
server.unregisterConnection(this); server.unregisterConnection(this);
server.getEventManager().fireAndForget(new DisconnectEvent(this)); server.getEventManager().fire(new DisconnectEvent(this))
.thenRun(() -> this.teardownFuture.complete(null));
}
public CompletableFuture<Void> getTeardownFuture() {
return teardownFuture;
} }
@Override @Override