Skip to content

Instantly share code, notes, and snippets.

@tanmatra
Created September 7, 2020 18:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tanmatra/5fa215204293bed7f2bd6295b731270d to your computer and use it in GitHub Desktop.
Save tanmatra/5fa215204293bed7f2bd6295b731270d to your computer and use it in GitHub Desktop.
import java.lang.reflect.InvocationHandler
import java.lang.reflect.Method
import java.lang.reflect.Proxy
import java.util.Timer
import kotlin.concurrent.timerTask
import kotlin.coroutines.Continuation
import kotlin.coroutines.intrinsics.COROUTINE_SUSPENDED
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.isActive
import kotlinx.coroutines.runBlocking
interface Service
{
suspend fun duplicate(arg: String): String
}
class ProxyHandler : InvocationHandler
{
override fun invoke(proxy: Any, method: Method, args: Array<out Any>?): Any {
if (method.declaringClass == Object::class.java) {
return method.invoke(proxy, args)
}
if (method.name == "duplicate") {
val arg = args!![0] as String
@Suppress("UNCHECKED_CAST")
val continuation = args[1] as Continuation<String>
val timer = Timer("background timer", true)
timer.schedule(timerTask {
if (!continuation.context.isActive) { // cancellation - is it right?
continuation.resumeWithException(CancellationException("Terminated"))
return@timerTask
}
if (arg.length == 1) {
continuation.resumeWithException(RuntimeException("Bad argument"))
} else {
continuation.resume("$arg,$arg")
}
}, 1000L)
return COROUTINE_SUSPENDED
}
error("Unknow method")
}
}
fun main() {
val iface = Service::class.java
val proxy = Proxy.newProxyInstance(iface.classLoader, arrayOf(iface), ProxyHandler()) as Service
runBlocking {
try {
val result1 = proxy.duplicate("A")
println("result1 = $result1")
} catch (e: Exception) {
System.err.println("Error 1")
e.printStackTrace()
}
try {
val result2 = proxy.duplicate("BC")
println("result2 = $result2")
} catch (e: Exception) {
System.err.println("Error 2")
e.printStackTrace()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment