1
0
Fork 1
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:
carbotaniuman 2021-01-25 12:22:07 -06:00
parent f649c97eb1
commit e2130823a0
3 changed files with 35 additions and 50 deletions

View file

@ -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()

View file

@ -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) {

View file

@ -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" }
} }