feat: add ProxyPreShutdownEvent before players are disconnected (#1626)
* feat: delay player disconnect until ProxyShutdownEvent completes * fix: added back empty line * feat: added ProxyPreShutdownEvent * feat: CR changes * chore: fixed license, annotated with Beta annotation * Update proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java Co-authored-by: Timon Seidel <timong.seidel@gmail.com> * Update proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java Co-authored-by: Timon Seidel <timong.seidel@gmail.com> * chore: consolidated log message * Update proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java Co-authored-by: Timon Seidel <timong.seidel@gmail.com> * Update proxy/src/main/java/com/velocitypowered/proxy/VelocityServer.java Co-authored-by: powercas_gamer <cas@mizule.dev> * Update api/src/main/java/com/velocitypowered/api/event/proxy/ProxyPreShutdownEvent.java Co-authored-by: powercas_gamer <cas@mizule.dev> * feat: make ProxyPreShutdownEvent timeout configurable via system property * fix: cs * Document velocity.pre-shutdown-timeout system property --------- Co-authored-by: Timon Seidel <timong.seidel@gmail.com> Co-authored-by: powercas_gamer <cas@mizule.dev> Co-authored-by: Adrian Gonzales <adriangonzalesval@gmail.com>
This commit is contained in:
@@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018-2025 Velocity Contributors
|
||||||
|
*
|
||||||
|
* The Velocity API is licensed under the terms of the MIT License. For more details,
|
||||||
|
* reference the LICENSE file in the api top-level directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.velocitypowered.api.event.proxy;
|
||||||
|
|
||||||
|
import com.google.common.annotations.Beta;
|
||||||
|
import com.velocitypowered.api.event.annotation.AwaitingEvent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This event is fired by the proxy after it has stopped accepting new connections,
|
||||||
|
* but before players are disconnected.
|
||||||
|
* This is the last point at which you can interact with currently connected players,
|
||||||
|
* for example to transfer them to another proxy or perform other cleanup tasks.
|
||||||
|
*
|
||||||
|
* @implNote Velocity will wait for all event listeners to complete before disconnecting players,
|
||||||
|
* but note that the event will time out after the configured value of the
|
||||||
|
* <code>velocity.pre-shutdown-timeout</code> system property, default 10 seconds,
|
||||||
|
* in seconds to prevent shutdown from hanging indefinitely
|
||||||
|
* @since 3.4.0
|
||||||
|
*/
|
||||||
|
@Beta
|
||||||
|
@AwaitingEvent
|
||||||
|
public final class ProxyPreShutdownEvent {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ProxyPreShutdownEvent";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,6 +24,7 @@ import com.google.gson.Gson;
|
|||||||
import com.google.gson.GsonBuilder;
|
import com.google.gson.GsonBuilder;
|
||||||
import com.velocitypowered.api.command.BrigadierCommand;
|
import com.velocitypowered.api.command.BrigadierCommand;
|
||||||
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
|
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
|
||||||
|
import com.velocitypowered.api.event.proxy.ProxyPreShutdownEvent;
|
||||||
import com.velocitypowered.api.event.proxy.ProxyReloadEvent;
|
import com.velocitypowered.api.event.proxy.ProxyReloadEvent;
|
||||||
import com.velocitypowered.api.event.proxy.ProxyShutdownEvent;
|
import com.velocitypowered.api.event.proxy.ProxyShutdownEvent;
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
@@ -150,6 +151,8 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
|
|||||||
)
|
)
|
||||||
.registerTypeHierarchyAdapter(Favicon.class, FaviconSerializer.INSTANCE)
|
.registerTypeHierarchyAdapter(Favicon.class, FaviconSerializer.INSTANCE)
|
||||||
.create();
|
.create();
|
||||||
|
private static final int PRE_SHUTDOWN_TIMEOUT =
|
||||||
|
Integer.getInteger("velocity.pre-shutdown-timeout", 10);
|
||||||
|
|
||||||
private final ConnectionManager cm;
|
private final ConnectionManager cm;
|
||||||
private final ProxyOptions options;
|
private final ProxyOptions options;
|
||||||
@@ -579,6 +582,20 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
|
|||||||
// done first to refuse new connections
|
// done first to refuse new connections
|
||||||
cm.shutdown();
|
cm.shutdown();
|
||||||
|
|
||||||
|
try {
|
||||||
|
eventManager.fire(new ProxyPreShutdownEvent())
|
||||||
|
.toCompletableFuture()
|
||||||
|
.get(PRE_SHUTDOWN_TIMEOUT, TimeUnit.SECONDS);
|
||||||
|
} catch (TimeoutException ignored) {
|
||||||
|
logger.warn("Your plugins took over {} seconds during pre shutdown.",
|
||||||
|
PRE_SHUTDOWN_TIMEOUT);
|
||||||
|
} catch (ExecutionException ee) {
|
||||||
|
logger.error("Exception in ProxyPreShutdownEvent handler; continuing shutdown.", ee);
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
logger.warn("Interrupted while waiting for ProxyPreShutdownEvent; continuing shutdown.");
|
||||||
|
}
|
||||||
|
|
||||||
ImmutableList<ConnectedPlayer> players = ImmutableList.copyOf(connectionsByUuid.values());
|
ImmutableList<ConnectedPlayer> players = ImmutableList.copyOf(connectionsByUuid.values());
|
||||||
for (ConnectedPlayer player : players) {
|
for (ConnectedPlayer player : players) {
|
||||||
player.disconnect(reason);
|
player.disconnect(reason);
|
||||||
|
|||||||
Reference in New Issue
Block a user