Update XsClient functionality for stress testing

16
Timo Bryant 2024-01-12 17:10:02 +01:00
parent 86f3f66d50
commit e2c13c2503
5 changed files with 72 additions and 27 deletions

View File

@ -12,6 +12,7 @@ import korlibs.korge.input.*
import korlibs.korge.tween.get
import korlibs.korge.tween.tween
import korlibs.korge.ui.tooltip
import korlibs.korge.ui.uiCheckBox
import korlibs.logger.AnsiEscape
import korlibs.math.geom.*
import korlibs.math.geom.shape.toShape2D
@ -89,6 +90,8 @@ class ViewDocument(private val document: Document) : Scene() {
val imageFile = localCurrentDirVfs["assets/xs-reg/00001.jpg"].readBitmap()
image(imageFile)
uiCheckBox { text = "foo" }
document.retrieveOcrPages().first().words.forEach { word ->
solidRect(
width = word.rectangle.width,

View File

@ -4,6 +4,7 @@ import com.github.ajalt.clikt.parameters.options.convert
import com.github.ajalt.clikt.parameters.options.option
import com.github.ajalt.clikt.parameters.options.required
import com.github.ajalt.clikt.parameters.types.int
import de.itkl.httpClient.clients.TaskWaitStatus
import de.itkl.httpClient.clients.XsClient
import de.itkl.httpClient.httpClientModule
import kotlinx.coroutines.*
@ -15,6 +16,7 @@ import org.koin.core.context.GlobalContext.startKoin
import java.io.File
import java.nio.file.Path
import java.nio.file.Paths
import kotlin.time.Duration.Companion.minutes
class Cli : CliktCommand() {
override fun run() {}
@ -36,10 +38,14 @@ class XsCli : KoinComponent {
private val xsClient: XsClient by inject()
suspend fun run(tasks: Int, inputDirectory: Path) = coroutineScope {
val files = inputDirectory.toFile().listFiles()!!.toList().filter { it.isFile }.filter { it.extension in listOf("pdf", "ttf", "jpg", "jpeg") }
val files = inputDirectory.toFile()
.listFiles()!!
.toList()
.filter { it.isFile }.filter { it.extension in listOf("pdf", "ttf", "jpg", "jpeg") }
.filter { !it.name.startsWith(".") }
val random = Random()
(0..tasks)
val (success, error) = (0..<tasks)
.map {
val file = files[random.nextInt(files.size)]
async {
@ -48,6 +54,9 @@ class XsCli : KoinComponent {
}
}
.awaitAll()
.partition { it.status == TaskWaitStatus.SUCCESS }
println("Summary: ${success.size + error.size}: ${success.size}/${error.size}")
}
}
@ -55,6 +64,5 @@ suspend fun main(args: Array<String>) {
startKoin {
modules(httpClientModule)
}
XsCli().run(tasks = 1, inputDirectory = Paths.get("assets/xs-reg"))
// Cli().main(args)
XsCli().run(tasks = 100, inputDirectory = Paths.get("assets/xs-reg"))
}

View File

@ -29,16 +29,27 @@ private val Log = KotlinLogging.logger { }
class XsClient : KoinComponent {
private val httpClient by inject<HttpClient>()
suspend fun waitFor(task: XsTask) {
suspend fun waitFor(task: XsTask): WaitForResponse {
Log.info { "Wait for competition: $task" }
val response = httpClient.get {
url("http://localhost:8080/api/v1/analyse/tasks/wait/${task.xsTaskId.taskId}")
user = "xs.dev.klara"
}
val responseText = response.bodyAsText()
Log.info { "Waiting done for task $task: ${response.status}: $responseText" }
val result = response.body<WaitForResponse>()
Log.info { "Waiting done for task $task: ${response.status}: $result" }
return result
}
suspend fun analyseResult(task: XsTask) {
val response = httpClient.get {
url("http://localhost:8080/api/v1/analyse-async-result/${task.xsTaskId.taskId}")
user = "xs.dev.klara"
}
check(response.status.isSuccess()) {
"HTTP Error"
}
val text = response.bodyAsText()
println(text)
}
suspend fun analyse(image: Path): TaskReference {
Log.info { "Starting analysis for image at path: $image" }
@ -105,6 +116,18 @@ data class XsTaskId(val tenantId: String, val taskId: String) {
}
}
@Serializable
data class WaitForResponse(
val xsTaskId: XsTaskId,
val status: TaskWaitStatus,
)
@Serializable
enum class TaskWaitStatus {
ERROR,
SUCCESS
}
fun Path.toChannelProvider(): ChannelProvider {
val file = toFile()
return ChannelProvider(file.length()) { file.readChannel() }

View File

@ -16,7 +16,7 @@ fun createHttpClient(): HttpClient {
}
install(smartCloudAuthPlugin)
install(HttpTimeout) {
requestTimeoutMillis = 1.minutes.inWholeMilliseconds
requestTimeoutMillis = 30.minutes.inWholeMilliseconds
}
engine {

View File

@ -3,6 +3,7 @@ package de.itkl.httpClient.implementation
import com.github.benmanes.caffeine.cache.Caffeine
import com.github.benmanes.caffeine.cache.Cache
import de.itkl.httpClient.auth.*
import de.itkl.httpClient.clients.user
import io.github.oshai.kotlinlogging.KotlinLogging
import io.ktor.client.*
import io.ktor.client.call.*
@ -13,12 +14,16 @@ import io.ktor.util.*
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import java.util.concurrent.TimeUnit
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
private val Log = KotlinLogging.logger { }
class SmartCloudAuthStrategy : AuthStrategy, KoinComponent {
private val credentialsProvider: CredentialsProvider by inject()
private val loginMutex = Mutex()
// Cache Helpers
private val tokenCache: Cache<String, AuthenticationToken> = Caffeine.newBuilder()
.expireAfterWrite(1, TimeUnit.HOURS)
@ -31,7 +36,12 @@ class SmartCloudAuthStrategy : AuthStrategy, KoinComponent {
return null
}
// Return cached token if present
tokenCache.getIfPresent(user)?.let {
Log.info { "Returning cached token for user: $user" }
return it
}
return loginMutex.withLock {
tokenCache.getIfPresent(user)?.let {
Log.info { "Returning cached token for user: $user" }
return it
@ -56,6 +66,7 @@ class SmartCloudAuthStrategy : AuthStrategy, KoinComponent {
// Cache the token after successful login
tokenCache.put(user, token)
return token
token
}
}
}