From 848e0ba170bc0da798a43f561490c9cb90dd5a1a Mon Sep 17 00:00:00 2001 From: Avi Kav Date: Wed, 5 Aug 2020 01:41:30 +0000 Subject: [PATCH] Revert "Revert "Merge branch 'fix-4xx-caching' into expermential_buffer_size_knob"" This reverts commit e85b77569b2b509ab5615745f13bfe163801e503 --- settings.sample.json | 4 ++++ src/main/kotlin/mdnet/base/Main.kt | 4 ++++ src/main/kotlin/mdnet/base/server/Application.kt | 2 +- src/main/kotlin/mdnet/base/server/ImageServer.kt | 16 +++++++++++++--- .../kotlin/mdnet/base/settings/ClientSettings.kt | 8 +++++++- 5 files changed, 29 insertions(+), 5 deletions(-) diff --git a/settings.sample.json b/settings.sample.json index 42d6432..c901804 100755 --- a/settings.sample.json +++ b/settings.sample.json @@ -13,5 +13,9 @@ "web_settings": { //delete this block to disable webui "ui_hostname": "127.0.0.1", // "127.0.0.1" is the default and binds to localhost only "ui_port": 8080 + }, + "experimental": { + "max_buffer_size_for_cache_hit": 0 // Size is n * 8kiB. 0 uses the JDK default (which is likely 8kiB). + // May improve diskIO at the cost of memory pressure. Testing needed } } diff --git a/src/main/kotlin/mdnet/base/Main.kt b/src/main/kotlin/mdnet/base/Main.kt index 9c1af90..7b1a5b2 100644 --- a/src/main/kotlin/mdnet/base/Main.kt +++ b/src/main/kotlin/mdnet/base/Main.kt @@ -129,6 +129,10 @@ object Main { dieWithError("Config Error: Invalid UI port number") } } + if (settings.experimental != null) { + if (settings.experimental.maxBufferSizeForCacheHit < 0) + dieWithError("Config Error: Max cache buffer multiple must be >= 0") + } } private const val CLIENT_KEY_LENGTH = 52 diff --git a/src/main/kotlin/mdnet/base/server/Application.kt b/src/main/kotlin/mdnet/base/server/Application.kt index 456128f..09b5748 100644 --- a/src/main/kotlin/mdnet/base/server/Application.kt +++ b/src/main/kotlin/mdnet/base/server/Application.kt @@ -63,7 +63,7 @@ fun getServer(cache: DiskLruCache, serverSettings: ServerSettings, clientSetting .setMaxConnPerRoute(3000) .build()) - val imageServer = ImageServer(cache, database, statistics, serverSettings, client) + val imageServer = ImageServer(cache, database, statistics, serverSettings, clientSettings, client) return timeRequest() .then(catchAllHideDetails()) diff --git a/src/main/kotlin/mdnet/base/server/ImageServer.kt b/src/main/kotlin/mdnet/base/server/ImageServer.kt index dec52dc..4b7b92a 100644 --- a/src/main/kotlin/mdnet/base/server/ImageServer.kt +++ b/src/main/kotlin/mdnet/base/server/ImageServer.kt @@ -48,6 +48,7 @@ import mdnet.base.data.ImageDatum import mdnet.base.data.Statistics import mdnet.base.data.Token import mdnet.base.info +import mdnet.base.settings.ClientSettings import mdnet.base.settings.ServerSettings import mdnet.base.trace import mdnet.base.warn @@ -66,6 +67,7 @@ class ImageServer( private val database: Database, private val statistics: AtomicReference, private val serverSettings: ServerSettings, + private val clientSettings: ClientSettings, private val client: HttpHandler ) { init { @@ -74,6 +76,9 @@ class ImageServer( } } private val executor = Executors.newCachedThreadPool() + private val maxBufferSizeForCacheHit: Int? = clientSettings.experimental?.maxBufferSizeForCacheHit + ?.takeUnless { it == 0 } + ?.times(8 * 1024) fun handler(dataSaver: Boolean, tokenized: Boolean = false): HttpHandler { val sodium = LazySodiumJava(SodiumJava()) @@ -203,11 +208,16 @@ class ImageServer( } LOGGER.info { "Request for $sanitizedUri hit cache" } + val cacheStream = snapshot.getInputStream(0) + val bufferSize = maxBufferSizeForCacheHit?.coerceAtMost(snapshot.getLength(0).toInt()) + val bufferedStream = bufferSize?.let { + BufferedInputStream(cacheStream, bufferSize) + } ?: BufferedInputStream(cacheStream) // Todo: Move into builder. It's untidy having the null propagate all the way here but I'm tired and tomorrow is a fast day. respondWithImage( - CipherInputStream(BufferedInputStream(snapshot.getInputStream(0)), cipher), - snapshot.getLength(0).toString(), imageDatum.contentType, imageDatum.lastModified, - true + CipherInputStream(bufferedStream, cipher), + snapshot.getLength(0).toString(), imageDatum.contentType, imageDatum.lastModified, + true ) } } diff --git a/src/main/kotlin/mdnet/base/settings/ClientSettings.kt b/src/main/kotlin/mdnet/base/settings/ClientSettings.kt index f9254be..3798085 100644 --- a/src/main/kotlin/mdnet/base/settings/ClientSettings.kt +++ b/src/main/kotlin/mdnet/base/settings/ClientSettings.kt @@ -35,7 +35,8 @@ data class ClientSettings( val threads: Int = 4, val gracefulShutdownWaitSeconds: Int = 60, val webSettings: WebSettings? = null, - val devSettings: DevSettings? = null + val devSettings: DevSettings? = null, + val experimental: Experimental? = null ) @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy::class) @@ -48,3 +49,8 @@ data class WebSettings( data class DevSettings( val isDev: Boolean = false ) + +@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy::class) +data class Experimental( + val maxBufferSizeForCacheHit: Int = 0 +)