From 48849063a4d30dfd5af418ed77c42c293406ad91 Mon Sep 17 00:00:00 2001 From: norangebit Date: Wed, 25 Mar 2020 22:07:23 +0100 Subject: [PATCH] add coroutines --- .../kotlin/drills/drill03/exercise1/Main.kt | 8 +++- .../drills/drill03/exercise3/AddTask.kt | 7 ---- .../kotlin/drills/drill03/exercise3/Client.kt | 26 ------------- .../drills/drill03/exercise3/FactTask.kt | 9 ----- .../kotlin/drills/drill03/exercise3/Rev.kt | 15 ------- .../kotlin/drills/drill03/exercise3/Server.kt | 11 ------ .../kotlin/drills/drill03/exercise3/Task.kt | 7 ---- .../kotlin/util/active/ActiveObjectHandler.kt | 39 ++++++++++++------- 8 files changed, 32 insertions(+), 90 deletions(-) delete mode 100644 src/main/kotlin/drills/drill03/exercise3/AddTask.kt delete mode 100644 src/main/kotlin/drills/drill03/exercise3/Client.kt delete mode 100644 src/main/kotlin/drills/drill03/exercise3/FactTask.kt delete mode 100644 src/main/kotlin/drills/drill03/exercise3/Rev.kt delete mode 100644 src/main/kotlin/drills/drill03/exercise3/Server.kt delete mode 100644 src/main/kotlin/drills/drill03/exercise3/Task.kt diff --git a/src/main/kotlin/drills/drill03/exercise1/Main.kt b/src/main/kotlin/drills/drill03/exercise1/Main.kt index 04df5ab..360fed2 100644 --- a/src/main/kotlin/drills/drill03/exercise1/Main.kt +++ b/src/main/kotlin/drills/drill03/exercise1/Main.kt @@ -1,12 +1,14 @@ package drills.drill03.exercise1 +import kotlinx.coroutines.cancelAndJoin +import kotlinx.coroutines.runBlocking import util.active.toActive import kotlin.time.ExperimentalTime import kotlin.time.measureTime @ExperimentalTime -fun main() { - val math = MathImpl().toActive(Math::class.java) +fun main() = runBlocking { + val (math, job) = MathImpl().toActive(Math::class.java) val elapsed = measureTime { for (i in 0 until 1000) @@ -14,4 +16,6 @@ fun main() { } println("Elapsed time: $elapsed") + + job.cancelAndJoin() } diff --git a/src/main/kotlin/drills/drill03/exercise3/AddTask.kt b/src/main/kotlin/drills/drill03/exercise3/AddTask.kt deleted file mode 100644 index bed31ae..0000000 --- a/src/main/kotlin/drills/drill03/exercise3/AddTask.kt +++ /dev/null @@ -1,7 +0,0 @@ -package drills.drill03.exercise3 - -import java.io.Serializable - -class AddTask(private val a: Int, private val b: Int) : Task { - override fun execute(): Serializable = a + b -} \ No newline at end of file diff --git a/src/main/kotlin/drills/drill03/exercise3/Client.kt b/src/main/kotlin/drills/drill03/exercise3/Client.kt deleted file mode 100644 index 3b55ebc..0000000 --- a/src/main/kotlin/drills/drill03/exercise3/Client.kt +++ /dev/null @@ -1,26 +0,0 @@ -package drills.drill03.exercise3 - -import util.rmi.Client - -fun main() { - Client(clientHandler).start() -} - -val clientHandler = { - val rev = Client.lookup("rev") as Rev - - println("Enter two numbers:") - val a = readLine()?.toInt() ?: 0 - val b = readLine()?.toInt() ?: 0 - - val sum = rev.executeTask(AddTask(a, b)) - println("The sum of $a and $b is $sum") - - println("Enter the number of which you want to calculate the factorial:") - val n = readLine()?.toInt() ?: 0 - - val fact = rev.executeTask(FactTask(n)) - println("The factorial of $n is $fact") -} - -fun fact(n: Int): Long = if (n <= 1) 1 else n * fact(n - 1) diff --git a/src/main/kotlin/drills/drill03/exercise3/FactTask.kt b/src/main/kotlin/drills/drill03/exercise3/FactTask.kt deleted file mode 100644 index e881dfb..0000000 --- a/src/main/kotlin/drills/drill03/exercise3/FactTask.kt +++ /dev/null @@ -1,9 +0,0 @@ -package drills.drill03.exercise3 - -import java.io.Serializable - -class FactTask(private val n: Int) : Task { - override fun execute(): Serializable = fact(n) - - private fun fact(n: Int): Long = if (n <= 1) 1 else n * fact(n - 1) -} \ No newline at end of file diff --git a/src/main/kotlin/drills/drill03/exercise3/Rev.kt b/src/main/kotlin/drills/drill03/exercise3/Rev.kt deleted file mode 100644 index a9d8b88..0000000 --- a/src/main/kotlin/drills/drill03/exercise3/Rev.kt +++ /dev/null @@ -1,15 +0,0 @@ -package drills.drill03.exercise3 - -import java.io.Serializable -import java.rmi.Remote -import java.rmi.RemoteException -import java.rmi.server.UnicastRemoteObject - -interface Rev : Remote { - @Throws(RemoteException::class) - fun executeTask(task: Task): Serializable -} - -class RevImpl : Rev, UnicastRemoteObject() { - override fun executeTask(task: Task): Serializable = task.execute() -} diff --git a/src/main/kotlin/drills/drill03/exercise3/Server.kt b/src/main/kotlin/drills/drill03/exercise3/Server.kt deleted file mode 100644 index 3622ccd..0000000 --- a/src/main/kotlin/drills/drill03/exercise3/Server.kt +++ /dev/null @@ -1,11 +0,0 @@ -package drills.drill03.exercise3 - -import util.rmi.Server - -fun main() { - Server { - System.setSecurityManager(SecurityManager()) - val rev: Rev = RevImpl() - Server.bind(rev, "rev") - }.start() -} diff --git a/src/main/kotlin/drills/drill03/exercise3/Task.kt b/src/main/kotlin/drills/drill03/exercise3/Task.kt deleted file mode 100644 index 8a7e785..0000000 --- a/src/main/kotlin/drills/drill03/exercise3/Task.kt +++ /dev/null @@ -1,7 +0,0 @@ -package drills.drill03.exercise3 - -import java.io.Serializable - -interface Task : Serializable { - fun execute(): Serializable -} \ No newline at end of file diff --git a/src/main/kotlin/util/active/ActiveObjectHandler.kt b/src/main/kotlin/util/active/ActiveObjectHandler.kt index ef17002..85d67ba 100644 --- a/src/main/kotlin/util/active/ActiveObjectHandler.kt +++ b/src/main/kotlin/util/active/ActiveObjectHandler.kt @@ -1,20 +1,18 @@ package util.active +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.isActive +import kotlinx.coroutines.launch import java.lang.reflect.InvocationHandler import java.lang.reflect.Method import java.lang.reflect.Proxy import java.util.concurrent.LinkedBlockingQueue +import java.util.concurrent.TimeUnit class ActiveObjectHandler(private val target: Any) : InvocationHandler { private val queue = LinkedBlockingQueue() - init { - Thread { - while (true) - queue.take().executeOn(target) - }.start() - } - override fun invoke(proxy: Any?, method: Method?, args: Array?): Any { if (method != null && args != null) queue.add(Call(method, args)) @@ -22,6 +20,15 @@ class ActiveObjectHandler(private val target: Any) : InvocationHandler { return Unit } + fun start(): Job { + return GlobalScope.launch { + while (isActive || queue.isNotEmpty()) { + queue.poll(100, TimeUnit.MILLISECONDS) + ?.executeOn(target) ?: continue + } + } + } + data class Call(val method: Method, val args: Array) { fun executeOn(target: Any) { method.invoke(target, *args) @@ -29,10 +36,16 @@ class ActiveObjectHandler(private val target: Any) : InvocationHandler { } } -fun Any.toActive(inter: Class): T { - return Proxy.newProxyInstance( - this::class.java.classLoader, - arrayOf(inter), - ActiveObjectHandler(this) - ) as T +fun Any.toActive(inter: Class): Pair { + val active = ActiveObjectHandler(this) + + val job = active.start() + + return Pair( + Proxy.newProxyInstance( + this::class.java.classLoader, + arrayOf(inter), + active + ) as T, job + ) }