Hi Tomáš, I think a flag in Return will work better than one in Call because the library doesn't know whether the caller plans to use pipelining at the time that the Call is sent, but on the callee end the library definitely knows when the results don't contain any capabilities.
I think this would be a good optimization to implement. I would add a field to Return like: finishNeeded @8 :Bool = true; Doc comment: If true, the receiver must send a Finish message for this call in order to release resources and before reusing the question ID. If false, then a Finish message is optional; the receiver can choose not to send a Finish message, in which case it is free to reuse the question ID in a new Call immediately. This is useful to implement an optimization: If the call results contain no capabilities, then there's no need for the callee to retain any state about the call after the Return message is sent, and therefore no reason for the caller to send a Finish. Any attempts to pipeline on the original call are clearly invalid (because there's nothing to pipeline on), and there are no capabilities that need to be released. Then update whichever implementations you care about. Note that Python uses the C++ implementation. rpc.c++ is... pretty complicated, but it might not be too hard to add this flag. You'll also want to add a test, of course. Alternatively, file an issue and I'll implement it when I have a chance. -Kenton On Wed, Aug 9, 2017 at 9:24 AM, Tomáš Gavenčiak <gave...@gmail.com> wrote: > Hi Kenton, > > thanks for the quick reply and clarification! I was not 100% sure the > server-side result (without capabilities) may not be reused in some way. I > was thinking about some flag system and I like your solution. (I was > thinking about a caller-set feature flag in addition but it is likely not > necessary). > > How can I help with specifying and implementing this? I would be happy to > give it a shot but would be grateful for some guidance. And how does it > align with any future plans you have for capnp? > > All the best, > Tomáš > > On Tue, Aug 8, 2017 at 6:24 PM, Kenton Varda <ken...@cloudflare.com> > wrote: > >> Hi Tomáš, >> >> Indeed, there may be some room for optimization here. It's a little >> tricky since *normally* the rule is that Question table entries are >> allocated and freed strictly by the caller, hence requiring a Call and a >> Finish. If we allow releasing a table entry to happen on the opposite side >> from allocation (as we do with the export/import tables) then we have to >> think carefully about race conditions. >> >> Perhaps we could add a bool to Return which allows the callee to say: "I >> don't need you to send a Finish." The callee would only set this bool in >> cases where there are no capabilities at all in the results. It would mark >> the table entry as "optimistically freed"* and could release all associated >> resources. >> >> The caller would still be allowed to send a Finish message, which it >> might do for two reasons: >> - Because it sent Finish before it had received Return, in an attempt to >> cancel the call. >> - Because it doesn't implement the new flag, so always sends Finish. >> >> So the callee should be prepared to receive a Finish for an >> "optimistically freed" table entry, in which case it changes the table >> entry's state to plain "free". It should also be prepared to receive no >> Finish, which means it may later receive a Call that re-allocates the table >> entry. >> >> Also, of course, the callee may receive promise-pipeline messages >> referencing this table entry. This would happen if the caller *expected* >> the results to contain a capability, which could be the case even if the >> results ultimately did not contain any such entry. In this case the callee >> would treat any pipelining attempts as if they were trying to pipeline on a >> null capability. >> >> I think this could work, but to be sure I'd have to review all the other >> places where question IDs are referenced. >> >> * Technically, it's not necessary for "optimistically freed" and "free" >> to be separate states, but at least for common low-numbered table entries >> this should be "almost free" to store and may help catch bugs. >> >> -Kenton >> >> On Tue, Aug 8, 2017 at 1:40 AM, <gave...@gmail.com> wrote: >> >>> Hi everyone, >>> >>> I apologize in advance if I have missed this in the docs or other >>> thread, but I have not been able to understand why, when a method gets >>> called, there are three packets being sent: call (@2), return (@3), finish >>> (@4) even if no capabilities are involved (except for the bootstrap). The >>> setup I have used is just plain "Hello world" type bootstrap interface like >>> "interface Hello { hello @0 (a :Text) -> (a :Text); }" and I saw it in >>> Python, C++ and Rust. (Same effect with any numeric call/return type). >>> (Observing the network traffic with wireshark.) >>> >>> Why is there the need for a finish message even when the returned >>> content contains no capabilities? (I figure that message may only point to >>> caps declared in its capTable.) >>> >>> When the return payload contains no capability, is it possible to >>> somehow reuse the server-side content? (I did not figure out how, wireshark >>> shows the data being sent back and forth.) Is anything from the reply >>> actually stored server-side after the server sends the return without caps? >>> >>> Until the client does delete the replied payload (for example because it >>> wants to keep the data in capnp without copying),,the finish is not sent >>> which might require the server to retain some info on the call (used ID? or >>> even the data?), even though I have not found it in the sources. >>> >>> (I believe it is not because of IDs, as for every client independently, >>> if the server receives e.g. an abort (actually a finish (@4)) with an ID it >>> has not receiver a call it has not returned yet, it can be sure the abort >>> is meant for an ID it has returned recently and can ignore the abort.) >>> >>> Note that this is not a big performance problem for my use-case but >>> since we are mostly sending simple one-time messages between long-lived >>> caps, it seems like a waste. >>> >>> Thanks for any clarification and all the great work! >>> Tomáš Gavenčiak >>> >>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Cap'n Proto" group. >>> To unsubscribe from this group and stop receiving emails from it, send >>> an email to capnproto+unsubscr...@googlegroups.com. >>> Visit this group at https://groups.google.com/group/capnproto. >>> >> >> > -- You received this message because you are subscribed to the Google Groups "Cap'n Proto" group. To unsubscribe from this group and stop receiving emails from it, send an email to capnproto+unsubscr...@googlegroups.com. Visit this group at https://groups.google.com/group/capnproto.