gnunet-svn
[Top][All Lists]
Advanced

[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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]