[fleet] tail call hotfix

GitOrigin-RevId: 8913cc6b19131c60dae6ad1a0380700b9877910f
This commit is contained in:
Alexander Shparun
2025-10-08 18:52:52 +00:00
committed by intellij-monorepo-bot
parent c3d006d45e
commit 7d1eb4c256
@@ -21,6 +21,7 @@ import kotlinx.serialization.json.Json
import fleet.multiplatform.shims.ConcurrentHashMap
import fleet.multiplatform.shims.ConcurrentHashSet
import fleet.util.async.withSupervisor
import kotlinx.serialization.builtins.serializer
import kotlin.coroutines.EmptyCoroutineContext
class RpcExecutor private constructor(
@@ -207,16 +208,24 @@ class RpcExecutor private constructor(
Json.encodeToJsonElement(InstanceId.serializer(), remoteObjectId)
}
else {
val (resultSerialized, streamDescriptors) = withSerializationContext("Result of ${message.displayName}", null, serviceScope) {
val kserializer = returnType.serializer(message.classMethodDisplayName())
json.encodeToJsonElement(kserializer, result)
// tail call optimization might pass our continuation to whatever function was last in the method and we will get its return value
// usually kotlin will ignore it and replace with Unit, but because we are invoking an abstract lambda it gets confused
// TODO not the best approach, obviously, but it works without changes in the compiler plugin
if (returnType is RemoteKind.Data && returnType.serializer == Unit.serializer()) {
json.encodeToJsonElement(Unit.serializer(), Unit)
}
else {
val (resultSerialized, streamDescriptors) = withSerializationContext("Result of ${message.displayName}", null, serviceScope) {
val kserializer = returnType.serializer(message.classMethodDisplayName())
json.encodeToJsonElement(kserializer, result)
}
streamDescriptors.forEach {
registeredStreams.add(registerStream(serviceScope, it, clientId))
streamDescriptors.forEach {
registeredStreams.add(registerStream(serviceScope, it, clientId))
}
resultSerialized
}
resultSerialized
}
logger.trace { "Sending result: requestId=${request.requestId}, result=$result" }