From d8bd9623fc671859bcae2dc513d749126884e103 Mon Sep 17 00:00:00 2001 From: Oleksandr Dzhychko Date: Tue, 26 Mar 2024 16:23:47 +0100 Subject: [PATCH] feat(model-server): increase default timeout for writing responses and add an option to set it Increased timeouts make streamed responses less sensitive to slow clients/slow connections. The version delta stream is one of such responses. --- .../org/modelix/model/server/CmdLineArgs.kt | 16 ++++++++++++++ .../kotlin/org/modelix/model/server/Main.kt | 22 ++++++++++++------- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/model-server/src/main/kotlin/org/modelix/model/server/CmdLineArgs.kt b/model-server/src/main/kotlin/org/modelix/model/server/CmdLineArgs.kt index fe3b7d8df2..93fa2f3808 100644 --- a/model-server/src/main/kotlin/org/modelix/model/server/CmdLineArgs.kt +++ b/model-server/src/main/kotlin/org/modelix/model/server/CmdLineArgs.kt @@ -8,6 +8,15 @@ import java.io.File import java.util.LinkedList internal class CmdLineArgs { + + companion object { + // When this option was implemented, the default value was 10s + // in [NettyApplicationEngine.Configuration.responseWriteTimeoutSeconds]. + // A higher default makes sense because an initial pull of the repository might take longer. + // Two minutes is a default to accommodate most use cases. + private const val DEFAULT_RESPONSE_WRITE_TIMEOUT_SECONDS: Int = 2 * 60 + } + @Parameter(names = ["-secret", "--secret"], description = "Path to the secretfile", converter = FileConverter::class) var secretFile = File("/secrets/modelsecret/modelsecret.txt") @@ -33,6 +42,13 @@ internal class CmdLineArgs { @Parameter(names = ["-port", "--port"], description = "Set port", converter = IntegerConverter::class) var port: Int? = null + @Parameter( + names = ["-response-write-timeout-seconds", "--response-write-timeout-seconds"], + description = "Timeout in seconds for sending responses to clients. Values smaller or equal to 0 disable the timeout. Defaults to $DEFAULT_RESPONSE_WRITE_TIMEOUT_SECONDS seconds if unset.", + converter = IntegerConverter::class, + ) + var responseWriteTimeoutSeconds: Int = DEFAULT_RESPONSE_WRITE_TIMEOUT_SECONDS + @Parameter(names = ["-set", "--set"], description = "Set values", arity = 2) var setValues: List = LinkedList() diff --git a/model-server/src/main/kotlin/org/modelix/model/server/Main.kt b/model-server/src/main/kotlin/org/modelix/model/server/Main.kt index 86398773a3..9e1d693b7f 100644 --- a/model-server/src/main/kotlin/org/modelix/model/server/Main.kt +++ b/model-server/src/main/kotlin/org/modelix/model/server/Main.kt @@ -86,14 +86,15 @@ object Main { return } - LOG.info("Max memory (bytes): " + Runtime.getRuntime().maxMemory()) + LOG.info("Max memory (bytes): ${Runtime.getRuntime().maxMemory()}") LOG.info("Server process started") - LOG.info("In memory: " + cmdLineArgs.inmemory) - LOG.info("Path to secret file: " + cmdLineArgs.secretFile) - LOG.info("Path to JDBC configuration file: " + cmdLineArgs.jdbcConfFile) - LOG.info("Schema initialization: " + cmdLineArgs.schemaInit) - LOG.info("Set values: " + cmdLineArgs.setValues) - LOG.info("Disable Swagger-UI: " + cmdLineArgs.noSwaggerUi) + LOG.info("In memory: ${cmdLineArgs.inmemory}") + LOG.info("Path to secret file: ${cmdLineArgs.secretFile}") + LOG.info("Path to JDBC configuration file: ${cmdLineArgs.jdbcConfFile}") + LOG.info("Schema initialization: ${cmdLineArgs.schemaInit}") + LOG.info("Set values: ${cmdLineArgs.setValues}") + LOG.info("Disable Swagger-UI: ${cmdLineArgs.noSwaggerUi}") + LOG.info("Response write timeout seconds: ${cmdLineArgs.responseWriteTimeoutSeconds}") if (cmdLineArgs.dumpOutName != null && !cmdLineArgs.inmemory) { throw RuntimeException("For now dumps are supported only with the inmemory option") @@ -163,7 +164,12 @@ object Main { val contentExplorer = ContentExplorer(localModelClient, repositoriesManager) val modelReplicationServer = ModelReplicationServer(repositoriesManager) val metricsHandler = MetricsHandler() - val ktorServer: NettyApplicationEngine = embeddedServer(Netty, port = port) { + + val configureNetty: NettyApplicationEngine.Configuration.() -> Unit = { + this.responseWriteTimeoutSeconds = cmdLineArgs.responseWriteTimeoutSeconds + } + + val ktorServer: NettyApplicationEngine = embeddedServer(Netty, port = port, configure = configureNetty) { install(Routing) installAuthentication(unitTestMode = !KeycloakUtils.isEnabled()) install(ForwardedHeaders)