Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle incoming receiverAnswer cap descriptors. #209

Merged
merged 24 commits into from
Jan 3, 2022

Conversation

zenhack
Copy link
Contributor

@zenhack zenhack commented Jan 1, 2022

Marking this as a draft, still TODO:

  • Some more tests. In particular, the current test only excercises bootstrap messages, we should of course test calls as well.
  • Scrutinize the logic in recvCap for choosing when to return local = true; This is subtle and I'm too tired to think it through carefully right now, will get back to it.

Note that this includes the changes from #207 and #208, so the diff is bigger than it should be.

This only actually gets used in sendCap(), but there we have a reference
to the corresponding client, so we can just call client.State() instead
of carrying around this parallel slice everywhere.
Useful to avoid needing to expand the if/else in-line everywhere.
...in preparation for handling incoming receiverAnswer caps.
Needs testing, and I'm not sure what the right value is to return for
local; need to think about it.
...which fails; need to debug.
I think I initially put this in to try to work around deadlock issues
with net.Pipe(), but that didn't work anyway, and is unnecessary now
that the test uses socketpair().
There is no field resultsCapTable, only resultCapTable.
This solves an issue I discovered where sendCap() does a linear search
on the exports table for each sent capability.

After a long discussion with Louis over matrix, we concluded that adding
a metadata object for clients was the best solution; there's a general
design awkwardness right now where the rpc system needs to be able to
inspect the client in various ways, but Client is defined in the main
package and tries to encapsulate its implementation details. To some
degree we are able to use Brand(), but this gets awkward quickly,
because:

1. ClientHook is an openly implementable interface, so we don't know
   all the posibilities in the rpc code.
2. As I've been working on supporting receiverAnswer, I've found
   pinning down all the implementations I defined in the library that
   need to be worried about is challenging.
3. Some of these implementations aren't even exported, or just return
   nil from Brand().

The Metadata object lets the rpc system manage the bookkeeping
information independently of the internals of a client.

I expect to use this for more in the future, but for now this lets
us avoid the linear search by just storing the export id for each
connection in the client's metadata.
This improves type safety at call sites. It's actually more code right
now, but I am working on a branch where I use these elsewhere.
At least one case where we should return local = true. Need to think
through the logic for everything else.
@zenhack zenhack marked this pull request as draft January 1, 2022 03:48
I have convinced myself that this is necessary, though note that this
is not a complete solution; I need to work out how this interacts with
embargo stuff everywhere else.
Rather than having recvCap deal with this directly, we now have a separate
routine that just checks if a client is local, which we invoke higher up
in the chain.

This means we're not trying to figure this out based on the cap
descriptor, which means (1) fewer cases, and (2), in the case of
a cap descriptor that denotes a promise or answer, we will be able
to recursively call this on the target -- whose original CapDescriptor
may not be known.

This introduces one minor functional change: ErrorClients are now
treated as local. This means we'll set up embargos for them, which
we don't *need* to do, but it shouldn't be a problem; calling methods
on errors is not a case that is terribly sensitive to the extra round
trip. We could try to rework ErrorClient to avoid this, but it doesn't
seem worth the trouble.
...and update our changes to recvCap to match.
@zenhack
Copy link
Contributor Author

zenhack commented Jan 2, 2022

Ok, I think the logic for local in recvCap is right now, though I still need to write some more tests. Relatedly, this also includes #212, which should be merged first.

This one projects off a call, rather than a bootstrap
@zenhack zenhack marked this pull request as ready for review January 2, 2022 23:52
@zenhack zenhack changed the title WIP: handle incoming receiverAnswer cap descriptors. Handle incoming receiverAnswer cap descriptors. Jan 2, 2022
@zenhack
Copy link
Contributor Author

zenhack commented Jan 2, 2022

Alright, added another test, which projects on calls. I consider this ready to go, but these should be reviewed & merged first:

lthibault
lthibault previously approved these changes Jan 3, 2022
Copy link
Collaborator

@lthibault lthibault left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Let's maybe merge #208 first?

rpc/answer.go Outdated
ans.pcall = nil
ans.flags |= resultsReady
// XXX: do we need to check if we've received a finish? if so, the
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The XXX suggests that this is a piece of missing implementation. Is that (still) the case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, fixed. Also fixed merge conflicts.

@lthibault lthibault merged commit dbd900b into capnproto:main Jan 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants