mirror of https://github.com/Minestom/Minestom.git
Merge 5430c62d61
into 5c050c66ca
This commit is contained in:
commit
a751940f40
|
@ -194,6 +194,10 @@ public final class MinecraftServer {
|
||||||
return !isStarted();
|
return !isStarted();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isStopped() {
|
||||||
|
return serverProcess.isStopped();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the chunk view distance of the server.
|
* Gets the chunk view distance of the server.
|
||||||
* <p>
|
* <p>
|
||||||
|
|
|
@ -137,10 +137,29 @@ public interface ServerProcess extends Snapshotable {
|
||||||
|
|
||||||
void start(@NotNull SocketAddress socketAddress);
|
void start(@NotNull SocketAddress socketAddress);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request the server to stop
|
||||||
|
*/
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shutdown all sub processes
|
||||||
|
* <p>
|
||||||
|
* Order:
|
||||||
|
* <ul>
|
||||||
|
* {@link SchedulerManager#shutdown()}
|
||||||
|
* {@link ConnectionManager#shutdown()}
|
||||||
|
* {@link Server#stop()}
|
||||||
|
* {@link BenchmarkManager#disable()}
|
||||||
|
* {@link ThreadDispatcher#shutdown()}
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
void shutdown();
|
||||||
|
|
||||||
boolean isAlive();
|
boolean isAlive();
|
||||||
|
|
||||||
|
boolean isStopped();
|
||||||
|
|
||||||
@ApiStatus.NonExtendable
|
@ApiStatus.NonExtendable
|
||||||
interface Ticker {
|
interface Ticker {
|
||||||
void tick(long nanoTime);
|
void tick(long nanoTime);
|
||||||
|
|
|
@ -71,6 +71,7 @@ final class ServerProcessImpl implements ServerProcess {
|
||||||
private final Ticker ticker;
|
private final Ticker ticker;
|
||||||
|
|
||||||
private final AtomicBoolean started = new AtomicBoolean();
|
private final AtomicBoolean started = new AtomicBoolean();
|
||||||
|
private final AtomicBoolean stopping = new AtomicBoolean();
|
||||||
private final AtomicBoolean stopped = new AtomicBoolean();
|
private final AtomicBoolean stopped = new AtomicBoolean();
|
||||||
|
|
||||||
public ServerProcessImpl() throws IOException {
|
public ServerProcessImpl() throws IOException {
|
||||||
|
@ -230,6 +231,13 @@ final class ServerProcessImpl implements ServerProcess {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stop() {
|
public void stop() {
|
||||||
|
if (!stopping.compareAndSet(false, true))
|
||||||
|
return;
|
||||||
|
LOGGER.info("Stopping " + MinecraftServer.getBrandName() + " server...");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shutdown() {
|
||||||
if (!stopped.compareAndSet(false, true))
|
if (!stopped.compareAndSet(false, true))
|
||||||
return;
|
return;
|
||||||
LOGGER.info("Stopping " + MinecraftServer.getBrandName() + " server.");
|
LOGGER.info("Stopping " + MinecraftServer.getBrandName() + " server.");
|
||||||
|
@ -242,9 +250,14 @@ final class ServerProcessImpl implements ServerProcess {
|
||||||
LOGGER.info(MinecraftServer.getBrandName() + " server stopped successfully.");
|
LOGGER.info(MinecraftServer.getBrandName() + " server stopped successfully.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isStopped() {
|
||||||
|
return stopped.get();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isAlive() {
|
public boolean isAlive() {
|
||||||
return started.get() && !stopped.get();
|
return started.get() && !stopping.get() && !stopped.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -23,6 +23,7 @@ public final class TickSchedulerThread extends MinestomThread {
|
||||||
public void run() {
|
public void run() {
|
||||||
long ticks = 0;
|
long ticks = 0;
|
||||||
long baseTime = System.nanoTime();
|
long baseTime = System.nanoTime();
|
||||||
|
|
||||||
while (serverProcess.isAlive()) {
|
while (serverProcess.isAlive()) {
|
||||||
final long tickStart = System.nanoTime();
|
final long tickStart = System.nanoTime();
|
||||||
try {
|
try {
|
||||||
|
@ -32,16 +33,20 @@ public final class TickSchedulerThread extends MinestomThread {
|
||||||
}
|
}
|
||||||
|
|
||||||
ticks++;
|
ticks++;
|
||||||
long nextTickTime = baseTime + ticks * TICK_TIME_NANOS;
|
// don't wait next tick if server is stopping/stopped
|
||||||
waitUntilNextTick(nextTickTime);
|
if (serverProcess.isAlive()) {
|
||||||
// Check if the server can not keep up with the tickrate
|
long nextTickTime = baseTime + ticks * TICK_TIME_NANOS;
|
||||||
// if it gets too far behind, reset the ticks & baseTime
|
waitUntilNextTick(nextTickTime);
|
||||||
// to avoid running too many ticks at once
|
// Check if the server can not keep up with the tickrate
|
||||||
if (System.nanoTime() > nextTickTime + TICK_TIME_NANOS * ServerFlag.SERVER_MAX_TICK_CATCH_UP) {
|
// if it gets too far behind, reset the ticks & baseTime
|
||||||
baseTime = System.nanoTime();
|
// to avoid running too many ticks at once
|
||||||
ticks = 0;
|
if (System.nanoTime() > nextTickTime + TICK_TIME_NANOS * ServerFlag.SERVER_MAX_TICK_CATCH_UP) {
|
||||||
|
baseTime = System.nanoTime();
|
||||||
|
ticks = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
serverProcess.shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void waitUntilNextTick(long nextTickTimeNanos) {
|
private void waitUntilNextTick(long nextTickTimeNanos) {
|
||||||
|
|
|
@ -5,8 +5,7 @@ import org.junit.jupiter.api.Test;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
|
||||||
import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
||||||
|
|
||||||
public class ServerProcessTest {
|
public class ServerProcessTest {
|
||||||
|
@ -21,6 +20,8 @@ public class ServerProcessTest {
|
||||||
assertDoesNotThrow(() -> process.get().start(new InetSocketAddress("localhost", 25565)));
|
assertDoesNotThrow(() -> process.get().start(new InetSocketAddress("localhost", 25565)));
|
||||||
assertThrows(Exception.class, () -> process.get().start(new InetSocketAddress("localhost", 25566)));
|
assertThrows(Exception.class, () -> process.get().start(new InetSocketAddress("localhost", 25566)));
|
||||||
assertDoesNotThrow(() -> process.get().stop());
|
assertDoesNotThrow(() -> process.get().stop());
|
||||||
|
assertFalse(() -> process.get().isAlive(), "Server is still alive");
|
||||||
|
assertDoesNotThrow(() -> process.get().shutdown());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -33,5 +34,7 @@ public class ServerProcessTest {
|
||||||
var ticker = process.ticker();
|
var ticker = process.ticker();
|
||||||
assertDoesNotThrow(() -> ticker.tick(System.currentTimeMillis()));
|
assertDoesNotThrow(() -> ticker.tick(System.currentTimeMillis()));
|
||||||
assertDoesNotThrow(process::stop);
|
assertDoesNotThrow(process::stop);
|
||||||
|
assertFalse(process::isAlive, "Server is still alive");
|
||||||
|
assertDoesNotThrow(process::shutdown);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue