kotlinx-rpc
kotlinx-rpc copied to clipboard
Provide some way for a KrpcTransport/KrpcServer implementation to know if a procedure call is done
This is related to https://github.com/Kotlin/kotlinx-rpc/issues/75.
After hacking a way a bit trying to adapt kotlinx-rpc to a serverless architecture, I hit an issue.
To illustrate the problem, lets review the architecture of serverless computing.
However, krpc assumes the traditional dedicated server architecture:
If we look at the KrpcTransport interface:
interface KrpcTransport {
fun send(message: KrpcTransportMessage)
fun receive(): KrpcTransportMessage
}
KrpcTransportMessage only encodes the messages itself, and not whether this is the last message.
sealed interface KrpcTransportMessage {
class StringMessage(val value: String) : KrpcTransportMessage
class BinaryMessage(val value: ByteArray) : KrpcTransportMessage
}
As such, there is no way to know whether to enter the last step in the first diagram, and shut down the machine, outside of trying to parse the value, or counting the amount of sent messages, which is very fragile.
Proposed solution
Add a terminateProcedureCall() method to KrpcTransport / KrpcServer
public abstract class KrpcServer {
+ /**
+ * Notifies that a unit of work has been done, and resources associated with this transport may be safely released.
+ * Implementation may safely ignore this method if they wish to reuse the same resources for multiple units of work (multiple procedure calls).
+ */
+ public open suspend fun terminateProcedureCall(): Unit {}
}
Or alternatively:
public interface KrpcTransport : CoroutineScope {
public suspend fun send(message: KrpcTransportMessage)
public suspend fun receive(): KrpcTransportMessage
+ public suspend fun terminateProcedureCall(): Unit {}
public suspend fun receiveCatching(): Result<KrpcTransportMessage> {
return runCatching { receive() }
}
}
Hey @natanfudge ! Thanks for the interest in the lib!
I have a question: I'm not sure I understand, when terminateProcedureCall is intended to be called?
@Mr3zee terminateProcedureCall must be called when handling the procedure call is done.
The workflow should be like this:
- Call KrpcTransport.receive() to get a request.
- Parse the request and send it to an RPC service implementation.
- Send the response(s) with KrpcTransport.send() (this includes dispatching events made by emitting to streams)
- Release resource with
terminateProcedureCall(). By calling this, krpc acknowledges the hosting computer may shut down immediately.
@Mr3zee Any thoughts?
Hi, @natanfudge haven't had a chance to think it though yet, when will do - I'll let you know. Thank you for the issue, though!
Recent changes in 0.8.0 might solve this problem?
https://kotlin.github.io/kotlinx-rpc/0-8-0.html#krpc-protocol-changes
KrpcClient sends REQUEST cancellation messages for every individually finished call, canceled or finished successfully
@natanfudge those are protocol internals you shouldn't rely on probably, at least until we say it is stable (which won't be true for a while)