WIP suspending coroutine calls
This commit is contained in:
parent
0c9949225f
commit
f2704218f2
|
@ -16,6 +16,7 @@
|
|||
package dorkbox.network.rmi
|
||||
|
||||
import dorkbox.network.connection.Connection
|
||||
import dorkbox.network.connection.ListenerManager
|
||||
import dorkbox.network.other.coroutines.SuspendFunctionTrampoline
|
||||
import dorkbox.network.rmi.messages.MethodRequest
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
@ -112,39 +113,27 @@ internal class RmiClient(val isGlobal: Boolean,
|
|||
|
||||
|
||||
// if we are async, then this will immediately return
|
||||
@Suppress("MoveVariableDeclarationIntoWhen")
|
||||
val result = responseStorage.waitForReply(isAsync, rmiWaiter, timeoutMillis)
|
||||
when (result) {
|
||||
RmiResponseManager.TIMEOUT_EXCEPTION -> {
|
||||
// TODO: from top down, clean up the coroutine stack
|
||||
throw TimeoutException("Response timed out: ${method.declaringClass.name}.${method.name}(${method.parameterTypes.map{it.simpleName}})")
|
||||
val fancyName = RmiUtils.makeFancyMethodName(method)
|
||||
val exception = TimeoutException("Response timed out: $fancyName")
|
||||
// from top down, clean up the coroutine stack
|
||||
ListenerManager.cleanStackTrace(exception, RmiClient::class.java)
|
||||
throw exception
|
||||
}
|
||||
is Exception -> {
|
||||
// reconstruct the stack trace, so the calling method knows where the method invocation happened, and can trace the call
|
||||
// this stack will ALWAYS run up to this method (so we remove from the top->down, to get to the call site)
|
||||
|
||||
val stackTrace = Exception().stackTrace
|
||||
val myClassName = RmiClient::class.java.name
|
||||
|
||||
var newStartIndex = 0
|
||||
for (element in stackTrace) {
|
||||
newStartIndex++
|
||||
|
||||
if (element.className == myClassName && element.methodName == "invoke") {
|
||||
// we do this 1 more time, because we want to remove the proxy invocation off the stack as well.
|
||||
newStartIndex++
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
val newStack = Array<StackTraceElement>(result.stackTrace.size + stackTrace.size - newStartIndex) { stackTrace[0] }
|
||||
result.stackTrace.copyInto(newStack)
|
||||
stackTrace.copyInto(newStack, result.stackTrace.size, newStartIndex)
|
||||
|
||||
result.stackTrace = newStack
|
||||
ListenerManager.cleanStackTrace(Exception(), RmiClient::class.java, result)
|
||||
throw result
|
||||
}
|
||||
else -> {
|
||||
// val fancyName = RmiUtils.makeFancyMethodName(method)
|
||||
// val exception = TimeoutException("Response timed out: $fancyName")
|
||||
// // from top down, clean up the coroutine stack
|
||||
// ListenerManager.cleanStackTrace(exception, RmiClient::class.java)
|
||||
// throw exception
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
@ -218,15 +207,22 @@ internal class RmiClient(val isGlobal: Boolean,
|
|||
val maybeContinuation = args?.lastOrNull()
|
||||
|
||||
// async will return immediately
|
||||
val returnValue = if (maybeContinuation is Continuation<*>) {
|
||||
invokeSuspendFunction(maybeContinuation) {
|
||||
sendRequest(method, args)
|
||||
}
|
||||
} else {
|
||||
val returnValue =
|
||||
// if (maybeContinuation is Continuation<*>) {
|
||||
// try {
|
||||
// invokeSuspendFunction(maybeContinuation) {
|
||||
// sendRequest(method, args)
|
||||
// }
|
||||
// } catch (e: Exception) {
|
||||
// println("EXCEPT!")
|
||||
// }
|
||||
// // if this was an exception, we want to get it out!
|
||||
//
|
||||
// } else {
|
||||
runBlocking {
|
||||
sendRequest(method, args ?: EMPTY_ARRAY)
|
||||
}
|
||||
}
|
||||
// }
|
||||
|
||||
|
||||
if (!isAsync) {
|
||||
|
|
|
@ -375,9 +375,9 @@ internal class RmiMessageManager(logger: KLogger,
|
|||
insideResult.initCause(null)
|
||||
}
|
||||
|
||||
ListenerManager.cleanStackTrace(insideResult as Throwable)
|
||||
logger.error("Error invoking method: ${cachedMethod.method.declaringClass.name}.${cachedMethod.method.name}",
|
||||
insideResult)
|
||||
ListenerManager.cleanStackTraceReverse(insideResult as Throwable)
|
||||
val fancyName = RmiUtils.makeFancyMethodName(cachedMethod)
|
||||
logger.error("Error invoking method: $fancyName", insideResult)
|
||||
}
|
||||
insideResult
|
||||
}
|
||||
|
@ -415,9 +415,9 @@ internal class RmiMessageManager(logger: KLogger,
|
|||
result.initCause(null)
|
||||
}
|
||||
|
||||
ListenerManager.cleanStackTrace(result as Throwable)
|
||||
logger.error("Error invoking method: ${cachedMethod.method.declaringClass.name}.${cachedMethod.method.name}",
|
||||
result)
|
||||
ListenerManager.cleanStackTraceReverse(result as Throwable)
|
||||
val fancyName = RmiUtils.makeFancyMethodName(cachedMethod)
|
||||
logger.error("Error invoking method: $fancyName", result)
|
||||
}
|
||||
|
||||
if (sendResponse) {
|
||||
|
|
|
@ -438,4 +438,28 @@ object RmiUtils {
|
|||
fun unpackRight(packedInt: Int): Int {
|
||||
return packedInt.toShort().toInt()
|
||||
}
|
||||
|
||||
fun makeFancyMethodName(cachedMethod: CachedMethod): String {
|
||||
val parameterTypes = cachedMethod.method.parameterTypes
|
||||
val size = parameterTypes.size
|
||||
val args: String = if (size == 0 || parameterTypes[size - 1] == Continuation::class.java) {
|
||||
""
|
||||
} else {
|
||||
parameterTypes.joinToString { it.simpleName }
|
||||
}
|
||||
|
||||
return "${cachedMethod.method.declaringClass.name}.${cachedMethod.method.name}($args)"
|
||||
}
|
||||
|
||||
fun makeFancyMethodName(method: Method): String {
|
||||
val parameterTypes = method.parameterTypes
|
||||
val size = parameterTypes.size
|
||||
val args: String = if (size != 0 || parameterTypes[size - 1] == Continuation::class.java) {
|
||||
""
|
||||
} else {
|
||||
parameterTypes.joinToString { it.simpleName }
|
||||
}
|
||||
|
||||
return "${method.declaringClass.name}.${method.name}($args)"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user