[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libeufin] 01/02: monitoring scheduler perf.
From: |
gnunet |
Subject: |
[libeufin] 01/02: monitoring scheduler perf. |
Date: |
Tue, 11 Apr 2023 11:02:18 +0200 |
This is an automated email from the git hooks/post-receive script.
ms pushed a commit to branch master
in repository libeufin.
commit 743cf9ed4559f27a7fd21c314a69cb1d64b7d6af
Author: MS <ms@taler.net>
AuthorDate: Sun Apr 9 17:20:52 2023 +0200
monitoring scheduler perf.
---
.../main/kotlin/tech/libeufin/nexus/Scheduling.kt | 20 ++-
nexus/src/test/kotlin/SchedulingTest.kt | 168 +++++++++++++++++++++
nexus/src/test/kotlin/SchedulingTesting.kt | 43 ------
3 files changed, 185 insertions(+), 46 deletions(-)
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Scheduling.kt
b/nexus/src/main/kotlin/tech/libeufin/nexus/Scheduling.kt
index e23f5ffb..fd34faec 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/Scheduling.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/Scheduling.kt
@@ -34,8 +34,9 @@ import java.lang.IllegalArgumentException
import java.time.Duration
import java.time.Instant
import java.time.ZonedDateTime
-import java.util.concurrent.Executors
-import java.util.concurrent.TimeUnit
+import java.util.*
+import kotlin.concurrent.schedule
+import kotlin.coroutines.coroutineContext
import kotlin.system.exitProcess
private data class TaskSchedule(
@@ -151,10 +152,23 @@ private suspend fun operationScheduler(httpClient:
HttpClient) {
}
}
+
+// Alternative scheduler based on Java Timer, but same perf. as the while-true
one.
+/*
+private val javaTimer = Timer()
+suspend fun javaTimerOperationScheduler(httpClient: HttpClient) {
+ operationScheduler(httpClient)
+ javaTimer.schedule(
+ delay = 1000L,
+ action = { runBlocking { javaTimerOperationScheduler(httpClient) } }
+ )
+}
+*/
+
suspend fun whileTrueOperationScheduler(httpClient: HttpClient) {
while (true) {
operationScheduler(httpClient)
// Wait a bit
- delay(Duration.ofSeconds(1))
+ delay(Duration.ofSeconds(5))
}
}
\ No newline at end of file
diff --git a/nexus/src/test/kotlin/SchedulingTest.kt
b/nexus/src/test/kotlin/SchedulingTest.kt
new file mode 100644
index 00000000..4cb54390
--- /dev/null
+++ b/nexus/src/test/kotlin/SchedulingTest.kt
@@ -0,0 +1,168 @@
+import io.ktor.client.*
+import io.ktor.client.plugins.*
+import io.ktor.client.request.*
+import io.ktor.http.*
+import io.ktor.server.testing.*
+import kotlinx.coroutines.*
+import org.junit.Ignore
+import org.junit.Test
+import tech.libeufin.nexus.bankaccount.fetchBankAccountTransactions
+import tech.libeufin.nexus.server.FetchLevel
+import tech.libeufin.nexus.server.FetchSpecAllJson
+import tech.libeufin.nexus.whileTrueOperationScheduler
+import tech.libeufin.sandbox.sandboxApp
+import java.util.*
+import kotlin.concurrent.schedule
+import kotlin.text.get
+
+/**
+ * This test suite helps to _measure_ the scheduler performance.
+ * It is NOT meant to assert on values, but rather to _launch_ and
+ * give the chance to monitor the CPU usage with TOP(1)
+ */
+
+// This class focuses on the perf. of Nexus scheduling.
+class SchedulingTest {
+ // Launching the scheduler to measure its perf with TOP(1)
+ @Ignore // Ignoring because no assert takes place.
+ @Test
+ fun normalOperation() {
+ withTestDatabase {
+ prepNexusDb()
+ prepSandboxDb()
+ testApplication {
+ application(sandboxApp)
+ whileTrueOperationScheduler(client)
+ // javaTimerOperationScheduler(client)
+ }
+ }
+ runBlocking {
+ launch { awaitCancellation() }
+ }
+ }
+
+ // Allows TOP(1) on the bare connection operations without the scheduling
overhead.
+ // Not strictly related to scheduling, but perf. is a major part of
scheduling.
+ @Test
+ @Ignore // Ignoring because no assert takes place.
+ fun bareOperationXLibeufinBank() {
+ withTestDatabase {
+ prepNexusDb()
+ prepSandboxDb()
+ testApplication {
+ application(sandboxApp)
+ runBlocking {
+ while (true) {
+ // Even x-libeufin-bank takes 10-20% CPU
+ fetchBankAccountTransactions(
+ client,
+ fetchSpec = FetchSpecAllJson(
+ level = FetchLevel.STATEMENT,
+ bankConnection = "bar"
+ ),
+ accountId = "bar"
+ )
+ delay(1000L)
+ }
+ }
+ }
+ }
+ }
+ // Same as the previous, but on a EBICS connection.
+ // Perf. is only slightly worse than the JSON based x-libeufin-bank
connection.
+ @Ignore // Ignoring because no assert takes place.
+ @Test
+ fun bareOperationEbics() {
+ withTestDatabase {
+ prepNexusDb()
+ prepSandboxDb()
+ testApplication {
+ application(sandboxApp)
+ runBlocking {
+ while (true) {
+ fetchBankAccountTransactions(
+ client,
+ fetchSpec = FetchSpecAllJson(
+ level = FetchLevel.STATEMENT,
+ bankConnection = "foo"
+ ),
+ accountId = "foo"
+ )
+ delay(1000L)
+ }
+ }
+ }
+ }
+ }
+
+ // HTTP requests loop, to measure perf. via TOP(1)
+ @Ignore // because no assert takes place.
+ @Test
+ fun plainSandboxReqLoop() {
+ withTestDatabase {
+ prepSandboxDb()
+ testApplication {
+ application(sandboxApp)
+ while (true) {
+ // This brings the CPU to > 10%
+ /*client.get("/demobanks/default/access-api/accounts/foo")
{
+ expectSuccess = true
+ contentType(ContentType.Application.Json)
+ basicAuth("foo", "foo")
+ }*/
+ // This brings the CPU between 3 and 10%
+ /*client.get("/demobanks/default/integration-api/config") {
+ expectSuccess = true
+ contentType(ContentType.Application.Json)
+ // This caused 3 to 9% CPU => did not cause more usage.
+ // basicAuth("foo", "foo")
+ }*/
+ // Between 2 and 3% CPU.
+ client.get("/")
+ delay(1000L)
+ }
+ }
+ }
+ }
+}
+
+// This class investigates two ways of scheduling, regardless of the one used
by Nexus.
+class PlainJavaScheduling {
+ val instanceTimer = Timer()
+ // Below 5% CPU time.
+ private fun loopWithJavaTimer() {
+ println("with Java Timer " +
+ "doing at ${System.currentTimeMillis() / 1000}.."
+ ) // uncertain time goes by.
+ instanceTimer.schedule(
+ delay = 1200,
+ action = { loopWithJavaTimer() }
+ )
+ }
+ // Below 5% CPU time.
+ private suspend fun loopWithWhileTrue() {
+ val client = HttpClient()
+ while (true) {
+ println("With while-true " +
+ "doing at ${System.currentTimeMillis() / 1000}.."
+ ) // uncertain time goes by.
+ client.get("https://exchange.demo.taler.net/wrong") {
+ basicAuth("foo", "foo")
+ }
+ delay(1000)
+ }
+ }
+ @Ignore // due to no assert.
+ @Test
+ fun javaTimerLoop() {
+ loopWithJavaTimer()
+ runBlocking { delay(timeMillis = 30000) }
+ }
+ @Ignore // due to no assert.
+ @Test
+ fun whileTrueLoop() {
+ runBlocking {
+ loopWithWhileTrue()
+ }
+ }
+}
\ No newline at end of file
diff --git a/nexus/src/test/kotlin/SchedulingTesting.kt
b/nexus/src/test/kotlin/SchedulingTesting.kt
deleted file mode 100644
index 4f0cc605..00000000
--- a/nexus/src/test/kotlin/SchedulingTesting.kt
+++ /dev/null
@@ -1,43 +0,0 @@
-import io.ktor.client.*
-import io.ktor.server.testing.*
-import kotlinx.coroutines.*
-import org.junit.Ignore
-import org.junit.Test
-import tech.libeufin.nexus.whileTrueOperationScheduler
-import tech.libeufin.sandbox.sandboxApp
-import java.util.concurrent.Executors
-import java.util.concurrent.TimeUnit
-
-class SchedulingTesting {
- // Testing the 'sleep' technique of the scheduler, to watch with TOP(1)
- @Ignore // Just an experimental piece. No assertion takes place, nor its
logic is used anywhere.
- @Test
- fun sleep1SecWithDelay() {
- val sched = Executors.newScheduledThreadPool(1)
- sched.scheduleAtFixedRate(
- { println(".") },
- 1,
- 1,
- TimeUnit.SECONDS
- )
- runBlocking {
- launch { awaitCancellation() }
- }
- }
- // Launching the scheduler to measure its perf with TOP(1)
- @Ignore
- @Test
- fun normalOperation() {
- withTestDatabase {
- prepNexusDb()
- prepSandboxDb()
- testApplication {
- application(sandboxApp)
- whileTrueOperationScheduler(client)
- }
- }
- runBlocking {
- launch { awaitCancellation() }
- }
- }
-}
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.