mirror of
https://gitlab.com/mangadex-pub/mangadex_at_home.git
synced 2024-01-19 02:48:37 +00:00
Update settings handling
This commit is contained in:
parent
f649c97eb1
commit
e2130823a0
|
@ -22,9 +22,8 @@ import com.fasterxml.jackson.databind.DeserializationFeature
|
||||||
import com.fasterxml.jackson.module.kotlin.KotlinModule
|
import com.fasterxml.jackson.module.kotlin.KotlinModule
|
||||||
import mdnet.ServerHandlerJackson.auto
|
import mdnet.ServerHandlerJackson.auto
|
||||||
import mdnet.logging.info
|
import mdnet.logging.info
|
||||||
import mdnet.settings.DevSettings
|
import mdnet.settings.ClientSettings
|
||||||
import mdnet.settings.RemoteSettings
|
import mdnet.settings.RemoteSettings
|
||||||
import mdnet.settings.ServerSettings
|
|
||||||
import org.apache.hc.client5.http.impl.DefaultSchemePortResolver
|
import org.apache.hc.client5.http.impl.DefaultSchemePortResolver
|
||||||
import org.apache.hc.client5.http.impl.classic.HttpClients
|
import org.apache.hc.client5.http.impl.classic.HttpClients
|
||||||
import org.apache.hc.client5.http.impl.routing.DefaultRoutePlanner
|
import org.apache.hc.client5.http.impl.routing.DefaultRoutePlanner
|
||||||
|
@ -48,17 +47,14 @@ object ServerHandlerJackson : ConfigurableJackson(
|
||||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||||
)
|
)
|
||||||
|
|
||||||
class BackendApi(
|
class BackendApi(private val settings: ClientSettings) {
|
||||||
private val serverSettings: ServerSettings,
|
private val serverAddress = settings.devSettings.devUrl ?: SERVER_ADDRESS
|
||||||
private val devSettings: DevSettings,
|
|
||||||
private val maxCacheSizeInMebibytes: Long
|
|
||||||
) {
|
|
||||||
private val client = ApacheClient(
|
private val client = ApacheClient(
|
||||||
client = HttpClients.custom()
|
client = HttpClients.custom()
|
||||||
.setRoutePlanner(
|
.setRoutePlanner(
|
||||||
object : DefaultRoutePlanner(DefaultSchemePortResolver()) {
|
object : DefaultRoutePlanner(DefaultSchemePortResolver()) {
|
||||||
override fun determineLocalAddress(firstHop: HttpHost?, context: HttpContext?): InetAddress {
|
override fun determineLocalAddress(firstHop: HttpHost?, context: HttpContext?): InetAddress {
|
||||||
return InetAddress.getByName(serverSettings.hostname)
|
return InetAddress.getByName(settings.serverSettings.hostname)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -68,17 +64,18 @@ class BackendApi(
|
||||||
fun logoutFromControl(): Boolean {
|
fun logoutFromControl(): Boolean {
|
||||||
LOGGER.info { "Disconnecting from the control server" }
|
LOGGER.info { "Disconnecting from the control server" }
|
||||||
val params = mapOf<String, Any>(
|
val params = mapOf<String, Any>(
|
||||||
"secret" to serverSettings.secret
|
"secret" to settings.serverSettings.secret
|
||||||
)
|
)
|
||||||
|
|
||||||
val request = STRING_ANY_MAP_LENS(params, Request(Method.POST, getServerAddress() + "stop"))
|
val request = STRING_ANY_MAP_LENS(params, Request(Method.POST, serverAddress + "stop"))
|
||||||
val response = client(request)
|
val response = client(request)
|
||||||
|
|
||||||
return response.status.successful
|
return response.status.successful
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getPingParams(tlsCreatedAt: String? = null): Map<String, Any> =
|
private fun getPingParams(tlsCreatedAt: String? = null): Map<String, Any> {
|
||||||
mapOf(
|
val serverSettings = settings.serverSettings
|
||||||
|
return mapOf(
|
||||||
"secret" to serverSettings.secret,
|
"secret" to serverSettings.secret,
|
||||||
"port" to let {
|
"port" to let {
|
||||||
if (serverSettings.externalPort != 0) {
|
if (serverSettings.externalPort != 0) {
|
||||||
|
@ -87,7 +84,7 @@ class BackendApi(
|
||||||
serverSettings.port
|
serverSettings.port
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"disk_space" to maxCacheSizeInMebibytes * 1024 * 1024,
|
"disk_space" to settings.maxCacheSizeInMebibytes * 1024 * 1024,
|
||||||
"network_speed" to serverSettings.externalMaxKilobitsPerSecond * 1000 / 8,
|
"network_speed" to serverSettings.externalMaxKilobitsPerSecond * 1000 / 8,
|
||||||
"build_version" to Constants.CLIENT_BUILD
|
"build_version" to Constants.CLIENT_BUILD
|
||||||
).let {
|
).let {
|
||||||
|
@ -97,11 +94,18 @@ class BackendApi(
|
||||||
it
|
it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun loginToControl(): RemoteSettings? {
|
fun loginToControl(): RemoteSettings? {
|
||||||
LOGGER.info { "Connecting to the control server" }
|
LOGGER.info { "Connecting to the control server" }
|
||||||
|
|
||||||
val request = STRING_ANY_MAP_LENS(getPingParams(), Request(Method.POST, getServerAddress() + "ping"))
|
val request = STRING_ANY_MAP_LENS(
|
||||||
|
getPingParams(null),
|
||||||
|
Request(
|
||||||
|
Method.POST,
|
||||||
|
serverAddress + "ping"
|
||||||
|
)
|
||||||
|
)
|
||||||
val response = client(request)
|
val response = client(request)
|
||||||
|
|
||||||
return if (response.status.successful) {
|
return if (response.status.successful) {
|
||||||
|
@ -118,7 +122,7 @@ class BackendApi(
|
||||||
getPingParams(old.tls!!.createdAt),
|
getPingParams(old.tls!!.createdAt),
|
||||||
Request(
|
Request(
|
||||||
Method.POST,
|
Method.POST,
|
||||||
getServerAddress() + "ping"
|
serverAddress + "ping"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
val response = client(request)
|
val response = client(request)
|
||||||
|
@ -130,10 +134,6 @@ class BackendApi(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getServerAddress(): String {
|
|
||||||
return devSettings.devUrl ?: SERVER_ADDRESS
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val LOGGER = LoggerFactory.getLogger(BackendApi::class.java)
|
private val LOGGER = LoggerFactory.getLogger(BackendApi::class.java)
|
||||||
private val STRING_ANY_MAP_LENS = Body.auto<Map<String, Any>>().toLens()
|
private val STRING_ANY_MAP_LENS = Body.auto<Map<String, Any>>().toLens()
|
||||||
|
|
|
@ -105,10 +105,7 @@ class MangaDexClient(private val settingsFile: File, databaseFile: File, cacheFo
|
||||||
}
|
}
|
||||||
LOGGER.info { "Server manager starting" }
|
LOGGER.info { "Server manager starting" }
|
||||||
imageServer = ServerManager(
|
imageServer = ServerManager(
|
||||||
settings.serverSettings,
|
settings,
|
||||||
settings.devSettings,
|
|
||||||
settings.maxCacheSizeInMebibytes,
|
|
||||||
settings.metricsSettings,
|
|
||||||
storage
|
storage
|
||||||
).also {
|
).also {
|
||||||
it.start()
|
it.start()
|
||||||
|
@ -165,14 +162,8 @@ class MangaDexClient(private val settingsFile: File, databaseFile: File, cacheFo
|
||||||
|
|
||||||
storage.maxSize = (newSettings.maxCacheSizeInMebibytes * 1024 * 1024 * 0.95).toLong()
|
storage.maxSize = (newSettings.maxCacheSizeInMebibytes * 1024 * 1024 * 0.95).toLong()
|
||||||
|
|
||||||
val restartServer = newSettings.serverSettings != settings.serverSettings ||
|
stopImageServer()
|
||||||
newSettings.devSettings != settings.devSettings ||
|
startImageServer()
|
||||||
newSettings.metricsSettings != settings.metricsSettings
|
|
||||||
|
|
||||||
if (restartServer) {
|
|
||||||
stopImageServer()
|
|
||||||
startImageServer()
|
|
||||||
}
|
|
||||||
|
|
||||||
settings = newSettings
|
settings = newSettings
|
||||||
} catch (e: UnrecognizedPropertyException) {
|
} catch (e: UnrecognizedPropertyException) {
|
||||||
|
|
|
@ -27,10 +27,7 @@ import mdnet.logging.info
|
||||||
import mdnet.logging.warn
|
import mdnet.logging.warn
|
||||||
import mdnet.metrics.DefaultMicrometerMetrics
|
import mdnet.metrics.DefaultMicrometerMetrics
|
||||||
import mdnet.server.getServer
|
import mdnet.server.getServer
|
||||||
import mdnet.settings.DevSettings
|
import mdnet.settings.*
|
||||||
import mdnet.settings.MetricsSettings
|
|
||||||
import mdnet.settings.RemoteSettings
|
|
||||||
import mdnet.settings.ServerSettings
|
|
||||||
import org.http4k.server.Http4kServer
|
import org.http4k.server.Http4kServer
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import java.util.concurrent.CountDownLatch
|
import java.util.concurrent.CountDownLatch
|
||||||
|
@ -41,7 +38,7 @@ import java.util.concurrent.atomic.AtomicReference
|
||||||
sealed class State
|
sealed class State
|
||||||
|
|
||||||
// server is not running
|
// server is not running
|
||||||
data class Uninitialized(val serverSettings: ServerSettings, val devSettings: DevSettings) : State()
|
object Uninitialized : State()
|
||||||
|
|
||||||
// server has shut down
|
// server has shut down
|
||||||
object Shutdown : State()
|
object Shutdown : State()
|
||||||
|
@ -50,18 +47,15 @@ object Shutdown : State()
|
||||||
data class GracefulStop(
|
data class GracefulStop(
|
||||||
val lastRunning: Running,
|
val lastRunning: Running,
|
||||||
val counts: Int = 0,
|
val counts: Int = 0,
|
||||||
val nextState: State = Uninitialized(lastRunning.serverSettings, lastRunning.devSettings),
|
val nextState: State = Uninitialized,
|
||||||
val action: () -> Unit = {}
|
val action: () -> Unit = {}
|
||||||
) : State()
|
) : State()
|
||||||
|
|
||||||
// server is currently running
|
// server is currently running
|
||||||
data class Running(val server: Http4kServer, val settings: RemoteSettings, val serverSettings: ServerSettings, val devSettings: DevSettings) : State()
|
data class Running(val server: Http4kServer, val settings: RemoteSettings) : State()
|
||||||
|
|
||||||
class ServerManager(
|
class ServerManager(
|
||||||
serverSettings: ServerSettings,
|
private val settings: ClientSettings,
|
||||||
devSettings: DevSettings,
|
|
||||||
maxCacheSizeInMebibytes: Long,
|
|
||||||
private val metricsSettings: MetricsSettings,
|
|
||||||
private val storage: ImageStorage
|
private val storage: ImageStorage
|
||||||
) {
|
) {
|
||||||
// this must remain single-threaded because of how the state mechanism works
|
// this must remain single-threaded because of how the state mechanism works
|
||||||
|
@ -77,8 +71,8 @@ class ServerManager(
|
||||||
// end protected state
|
// end protected state
|
||||||
|
|
||||||
init {
|
init {
|
||||||
state = Uninitialized(serverSettings, devSettings)
|
state = Uninitialized
|
||||||
backendApi = BackendApi(serverSettings, devSettings, maxCacheSizeInMebibytes)
|
backendApi = BackendApi(settings)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun start() {
|
fun start() {
|
||||||
|
@ -117,7 +111,7 @@ class ServerManager(
|
||||||
val state = this.state
|
val state = this.state
|
||||||
|
|
||||||
if (state is GracefulStop) {
|
if (state is GracefulStop) {
|
||||||
val timesToWait = state.lastRunning.serverSettings.gracefulShutdownWaitSeconds / 5
|
val timesToWait = settings.serverSettings.gracefulShutdownWaitSeconds / 5
|
||||||
val requestCounters = registry.find("http.server.request.latency").timers()
|
val requestCounters = registry.find("http.server.request.latency").timers()
|
||||||
println(requestCounters)
|
println(requestCounters)
|
||||||
val curRequests = requestCounters.map { it.count() }.sum()
|
val curRequests = requestCounters.map { it.count() }.sum()
|
||||||
|
@ -164,7 +158,7 @@ class ServerManager(
|
||||||
val state = this.state
|
val state = this.state
|
||||||
if (state is Running) {
|
if (state is Running) {
|
||||||
val currentBytesSent = statistics.get().bytesSent - lastBytesSent
|
val currentBytesSent = statistics.get().bytesSent - lastBytesSent
|
||||||
if (state.serverSettings.maxMebibytesPerHour != 0L && state.serverSettings.maxMebibytesPerHour * 1024 * 1024 /* MiB to bytes */ < currentBytesSent) {
|
if (settings.serverSettings.maxMebibytesPerHour != 0L && settings.serverSettings.maxMebibytesPerHour * 1024 * 1024 /* MiB to bytes */ < currentBytesSent) {
|
||||||
LOGGER.info { "Stopping image server as hourly bandwidth limit reached" }
|
LOGGER.info { "Stopping image server as hourly bandwidth limit reached" }
|
||||||
|
|
||||||
this.state = GracefulStop(lastRunning = state)
|
this.state = GracefulStop(lastRunning = state)
|
||||||
|
@ -215,7 +209,7 @@ class ServerManager(
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loginAndStartServer() {
|
private fun loginAndStartServer() {
|
||||||
val state = this.state as Uninitialized
|
this.state as Uninitialized
|
||||||
|
|
||||||
val remoteSettings = backendApi.loginToControl()
|
val remoteSettings = backendApi.loginToControl()
|
||||||
?: throw RuntimeException("Failed to get a login response from server")
|
?: throw RuntimeException("Failed to get a login response from server")
|
||||||
|
@ -225,13 +219,13 @@ class ServerManager(
|
||||||
val server = getServer(
|
val server = getServer(
|
||||||
storage,
|
storage,
|
||||||
remoteSettings,
|
remoteSettings,
|
||||||
state.serverSettings,
|
settings.serverSettings,
|
||||||
statistics,
|
statistics,
|
||||||
metricsSettings,
|
settings.metricsSettings,
|
||||||
registry
|
registry
|
||||||
).start()
|
).start()
|
||||||
|
|
||||||
this.state = Running(server, remoteSettings, state.serverSettings, state.devSettings)
|
this.state = Running(server, remoteSettings)
|
||||||
LOGGER.info { "Internal HTTP server was successfully started" }
|
LOGGER.info { "Internal HTTP server was successfully started" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue