Cleaner server shutdown
This commit is contained in:
parent
0b3aac6189
commit
a2cc4ba6c3
@ -12,11 +12,7 @@ class IntegratedStarboundServer(val client: StarboundClient, root: File) : Starb
|
|||||||
|
|
||||||
override fun tick0(delta: Double) {
|
override fun tick0(delta: Double) {
|
||||||
if (client.isShutdown) {
|
if (client.isShutdown) {
|
||||||
shutdown()
|
close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun close0() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -49,9 +49,12 @@ import ru.dbotthepony.kstarbound.world.SystemWorld
|
|||||||
import ru.dbotthepony.kstarbound.world.SystemWorldLocation
|
import ru.dbotthepony.kstarbound.world.SystemWorldLocation
|
||||||
import ru.dbotthepony.kstarbound.world.UniversePos
|
import ru.dbotthepony.kstarbound.world.UniversePos
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
import java.util.concurrent.CompletableFuture
|
||||||
import java.util.concurrent.Future
|
import java.util.concurrent.Future
|
||||||
import java.util.concurrent.TimeUnit
|
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.concurrent.locks.ReentrantLock
|
||||||
import java.util.stream.Collectors
|
import java.util.stream.Collectors
|
||||||
import kotlin.collections.HashMap
|
import kotlin.collections.HashMap
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
@ -523,6 +526,15 @@ class ServerConnection(val server: StarboundServer, type: ConnectionType) : Conn
|
|||||||
// set to true so failed connection attempts don't appear in chat
|
// set to true so failed connection attempts don't appear in chat
|
||||||
private var announcedDisconnect = true
|
private var announcedDisconnect = true
|
||||||
private val isDisconnecting = AtomicBoolean()
|
private val isDisconnecting = AtomicBoolean()
|
||||||
|
private val disconnectSignal = CompletableFuture<Boolean>()
|
||||||
|
|
||||||
|
fun waitDisconnect(howLong: Long, timeUnit: TimeUnit): Boolean {
|
||||||
|
try {
|
||||||
|
return disconnectSignal.get(howLong, timeUnit)
|
||||||
|
} catch (err: Throwable) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun disconnect0(reason: String) {
|
private suspend fun disconnect0(reason: String) {
|
||||||
// make server forget shipworld right away
|
// make server forget shipworld right away
|
||||||
@ -601,8 +613,11 @@ class ServerConnection(val server: StarboundServer, type: ConnectionType) : Conn
|
|||||||
channel.flush()
|
channel.flush()
|
||||||
channel.close()
|
channel.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
disconnectSignal.complete(true)
|
||||||
} catch (err: Throwable) {
|
} catch (err: Throwable) {
|
||||||
LOGGER.error("Exception while disconnecting $this", err)
|
LOGGER.error("Exception while disconnecting $this", err)
|
||||||
|
disconnectSignal.complete(false)
|
||||||
} finally {
|
} finally {
|
||||||
// don't leave residue entities in worlds if we encountered an exception
|
// don't leave residue entities in worlds if we encountered an exception
|
||||||
tracker?.remove("Disconnect: $reason")
|
tracker?.remove("Disconnect: $reason")
|
||||||
@ -614,7 +629,9 @@ class ServerConnection(val server: StarboundServer, type: ConnectionType) : Conn
|
|||||||
|
|
||||||
override fun disconnect(reason: String) {
|
override fun disconnect(reason: String) {
|
||||||
if (isDisconnecting.compareAndSet(false, true)) {
|
if (isDisconnecting.compareAndSet(false, true)) {
|
||||||
server.scope.launch { disconnect0(reason) }
|
// launch with global scope because server will pause its own thread
|
||||||
|
// and wait for us to disconnect (if server is shutting down)
|
||||||
|
Starbound.GLOBAL_SCOPE.launch { disconnect0(reason) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,8 +467,10 @@ sealed class StarboundServer(val root: File) : BlockableEventLoop("Server thread
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun notifyWorldUnloaded(worldID: WorldID) {
|
fun notifyWorldUnloaded(worldID: WorldID) {
|
||||||
execute {
|
if (!isShutdown) {
|
||||||
worlds.remove(worldID)
|
execute {
|
||||||
|
worlds.remove(worldID)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -516,7 +518,11 @@ sealed class StarboundServer(val root: File) : BlockableEventLoop("Server thread
|
|||||||
return channels.connections.firstOrNull { it.uuid == uuid }
|
return channels.connections.firstOrNull { it.uuid == uuid }
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract fun close0()
|
protected open fun close() {
|
||||||
|
channels.close()
|
||||||
|
shutdown()
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract fun tick0(delta: Double)
|
protected abstract fun tick0(delta: Double)
|
||||||
|
|
||||||
private fun tick(delta: Double) {
|
private fun tick(delta: Double) {
|
||||||
@ -560,7 +566,6 @@ sealed class StarboundServer(val root: File) : BlockableEventLoop("Server thread
|
|||||||
database.commit()
|
database.commit()
|
||||||
databaseCleanable.clean()
|
databaseCleanable.clean()
|
||||||
universe.close()
|
universe.close()
|
||||||
close0()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -207,8 +207,10 @@ class ServerWorld private constructor(
|
|||||||
|
|
||||||
clients.forEach {
|
clients.forEach {
|
||||||
LOGGER.info("Kicking ${it.client.alias()} off dying world")
|
LOGGER.info("Kicking ${it.client.alias()} off dying world")
|
||||||
it.remove("World shutting down", setReturnWarp = false)
|
it.remove("World shutting down", setReturnWarp = !uncleanShutdown)
|
||||||
it.client.enqueueWarp(WarpAlias.Return)
|
|
||||||
|
if (!server.isShutdown)
|
||||||
|
it.client.enqueueWarp(WarpAlias.Return)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!uncleanShutdown) {
|
if (!uncleanShutdown) {
|
||||||
|
Loading…
Reference in New Issue
Block a user