grpc-swift icon indicating copy to clipboard operation
grpc-swift copied to clipboard

Provide Interceptor implementation that handles whole requests

Open Pante opened this issue 4 years ago • 4 comments

Is your feature request related to a problem? Please describe it.

This feature request is derived from #1181. At present, an Interceptor's receive(...) and send(...) methods process message parts individually. From my understanding, it means that performing a non-blocking operation on one part of a message may cause (other) parts of a message to be sent in the wrong order. To prevent such situations from arising, a developer has to maintain a buffer of message parts. In turn, this makes implementing an Interceptor with non-blocking operations both non-trivial and more painful than necessary.

A real world scenario where we encountered this problem is implementing an interceptor that attaches an authentication token to outgoing requests. In our case, we use Firebase authentication and tokens are retrieved asynchronously each time (we could cache the token, but caching a token is a entirely different can of worms that we really don't want to deal with). Since retrieving a token is non-blocking, and we want to perform an action on the header subsequently, we are forced to maintain our own buffer of message parts.

Describe the solution you'd like

It would be great if an alternative Interceptor implementation that handled whole message parts was provided. Something similar to gRPC implementations in other languages like Java and Dart. In that case, we don't have to deal with buffering message parts since we can just "fire-and-forget" so to speak, launching an async operation and sending the message once it has finished processing.

Describe alternatives you've considered

We have considered using a DispatcherSempahore to block an Interceptor until Firebase finishes retrieving a token but that just seems so hacky. Furthermore, we aren't sure of the interactions between

Additional context

I'm personally not sure how this will play out with the addition of async/await in Swift 5.5.

Pante avatar Jun 07 '21 15:06 Pante

Hey @Pante -- thanks for filing a detailed issue, this is definitely a problem that needs a better solution! Do you have any other scenarios where you'd need a different API?

I ask because rather than providing a completely separate interceptor implementation, I think gRPC should offer an interceptor which you can plug an authentication delegate into. The interceptor would take care of the state management (buffering and unbuffering message parts) and call out to the delegate with a way for it to asynchronously provide request headers. Would something like that work for you?

glbrntt avatar Jun 08 '21 08:06 glbrntt

Off the top of my head, I can't think of any other scenarios. I think that the interceptor delegate you describe works great! Although I don't have data to back this up, I feel that the majority of the async operations are performed on headers anyways so it fits perfectly.

Pante avatar Jun 09 '21 03:06 Pante

Hi, any news about this? I face the same issue.

CureleaAndrei avatar Apr 14 '22 16:04 CureleaAndrei

Hi, if there are no plans to support this directly, it would be great if a tutorial could be added on how to tackle this problem ourselves. Thanks

vykut avatar Dec 15 '22 17:12 vykut