orbit.client.addressable.InvocationSystem.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of orbit-client Show documentation
Show all versions of orbit-client Show documentation
Orbit is a system to make building highly scalable realtime services easier.
/*
Copyright (C) 2015 - 2019 Electronic Arts Inc. All rights reserved.
This file is part of the Orbit Project .
See license in LICENSE.
*/
package orbit.client.addressable
import kotlinx.coroutines.CompletableDeferred
import orbit.client.OrbitClientConfig
import orbit.client.execution.ExecutionSystem
import orbit.client.net.ClientState
import orbit.client.net.Completion
import orbit.client.net.LocalNode
import orbit.client.net.MessageHandler
import orbit.client.serializer.Serializer
import orbit.client.util.RemoteException
import orbit.shared.addressable.AddressableInvocation
import orbit.shared.addressable.AddressableInvocationArguments
import orbit.shared.net.Message
import orbit.shared.net.MessageContent
import orbit.shared.net.MessageTarget
import orbit.util.di.ComponentContainer
internal class InvocationSystem(
private val serializer: Serializer,
private val executionSystem: ExecutionSystem,
private val localNode: LocalNode,
componentContainer: ComponentContainer
) {
private val messageHandler by componentContainer.inject()
private val config by componentContainer.inject()
suspend fun onInvocationRequest(msg: Message) {
val content = msg.content as MessageContent.InvocationRequest
val arguments = serializer.deserialize(content.arguments)
val invocation = AddressableInvocation(
reference = content.destination,
method = content.method,
args = arguments
)
val completion: Completion = CompletableDeferred()
executionSystem.handleInvocation(invocation, completion)
val response = try {
val result = completion.await()
MessageContent.InvocationResponse(
data = serializer.serialize(result)
)
} catch (t: Throwable) {
if(config.platformExceptions) {
MessageContent.InvocationResponseError(t.toString(), serializer.serialize(t))
} else {
MessageContent.Error(t.toString())
}
}
messageHandler.sendMessage(
Message(
messageId = msg.messageId,
target = MessageTarget.Unicast(msg.source!!),
content = response
)
)
}
fun onInvocationResponse(ir: MessageContent.InvocationResponse, completion: Completion) {
val result = serializer.deserialize(ir.data)
completion.complete(result)
}
fun onInvocationPlatformErrorResponse(ire: MessageContent.InvocationResponseError, completion: Completion) {
val result = if(config.platformExceptions && !ire.platform.isNullOrEmpty()) {
serializer.deserialize(ire.platform!!)
} else {
RemoteException("Exceptional response received: ${ire.description}")
}
completion.completeExceptionally(result)
}
fun sendInvocation(invocation: AddressableInvocation): Completion {
check(localNode.status.clientState == ClientState.CONNECTED) { "The Orbit client is not connected" }
val arguments = serializer.serialize(invocation.args)
val msg = Message(
MessageContent.InvocationRequest(
destination = invocation.reference,
method = invocation.method,
arguments = arguments
)
)
return messageHandler.sendMessage(msg)
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy