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

Give access to request headers and ability to respond with custom headers #4

Open
standy66 opened this issue Jul 26, 2018 · 4 comments
Assignees
Milestone

Comments

@standy66
Copy link
Member

standy66 commented Jul 26, 2018

Need to address 4 use cases:

  1. Client wants to send additional request headers to server
  2. Client wants to read all of the response headers or trailers
  3. Server wants to read all of the request headers
  4. Server wants to send additional response headers or trailers to client

In gRPC, methods differ by cardinality: request may be either unary in both ways (UNARY_UNARY), client-side streaming (STREAM_UNARY), server-side streaming (UNARY_STREAM) and bidirectional streaming (STREAM_STREAM). Keeping that in mind, some cases listed above are far more difficult to design than the others.

@standy66 standy66 self-assigned this Nov 8, 2018
@standy66
Copy link
Member Author

Trying to address this in #8

@standy66
Copy link
Member Author

standy66 commented Jan 25, 2019

#8 got merged and addressed two simpler cases: 1st and 3rd. Clients can now send additional request headers with metadata keyword only argument:
stub.SayHello(request, metadata=(("x-api-key", "QWERTY"), ("x-request-id", "some-id")))
RPC handlers can get access to request metadata via optional last request argument:

async def SayHello(self, message, request):
  print("Server received metadata", request.custom_metadata)
  return HelloReply(message=base64.b64encode(pickle.dumps(request.custom_metadata)))

See more usage cases in unit tests

@standy66
Copy link
Member Author

standy66 commented Jan 25, 2019

Actually now that I think of it, it may be better to change optional argument name to something like context or request_info, to separate it from request message that arrived in handler (first argument in the example code above)

@standy66
Copy link
Member Author

standy66 commented Jan 25, 2019

Still 2nd and 4th case remain unimplemented. Here is some thoughts:

We can make two new yieldables: Headers and Trailers. Then we make socket to wait initiating response until either object of type Headers or first message is yielded. Similarly, the connection is closed on either Trailers or only after handler exits. The problem is that RPC cardinality is no longer tied to the function type: it can either by async generator or async function in both cases (multiple streaming response messages or just a single message). That's when it comes to server responding with custom headers/trailers.

For client reading headers/trailers it's different. I am yet to discover a way that works with async generators and is optional in a way that all existing code that does not check headers/trailers continues to work as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant