Client asks to bootstrap (question #0):
<< (bootstrap = (questionId = 0, deprecatedObjectId = <opaque pointer>)), (error = <nil>)
Client calls evaluate(expression(literal: 123))
, asks results to be sent to caller (itself), question #1.
Note that it calls evaluate
on the (promised) result of bootstrap.
<< (call = (questionId = 1, target = (promisedAnswer = (questionId = 0, transform = [])), interfaceId = 10923537602090224694, methodId = 0, allowThirdPartyTailCall = false, params = (content = <opaque pointer>, capTable = []), sendResultsTo = (caller = void))), (error = <nil>)
Server returns results for bootstrap (question #0): it's an interface (Calculator), which defines the method 'evaluate'.
>> (return = (answerId = 0, releaseParamCaps = false, results = (content = <opaque pointer>, capTable = [(senderHosted = 0)]))), (error = <nil>)
Client acknowledges the bootstrap. It has received the interface successfully, and releases question identifier #0, which means that in further calls, it will no longer be able to refer to this question. The server can free the memory associated with it, and either party can re-use id #0 to mean something else. (Messages are delivered in-order, so this works fine).
<< (release = (id = 0, referenceCount = 1)), (error = <nil>)
Server returns results for the first call (question #1): it's an interface (Value), which defines the method 'read'.
>> (return = (answerId = 1, releaseParamCaps = false, results = (content = <opaque pointer>, capTable = [(senderHosted = 1)]))), (error = <nil>)
Client (who has waited for question #1 to be answered), asks question #2, a call
to .read()
. The target of the call is an imported capability
- the Value
still
lives on the server. Results should be sent to the caller (the client).
<< (call = (questionId = 2, target = (importedCap = 1), interfaceId = 14116142932258867410, methodId = 0, allowThirdPartyTailCall = false, params = (content = <opaque pointer>, capTable = []), sendResultsTo = (caller = void))), (error = <nil>)
Server responds to question #2 with the raw float value (which we can't see, content is opaque because Go typing system...).
>> (return = (answerId = 2, releaseParamCaps = false, results = (content = <opaque pointer>, capTable = []))), (error = <nil>)
After that, the client closes the connection - it doesn't need to bother releasing the capability it's still holding (the Value it got from question #1), because closing releases everything.