-
Notifications
You must be signed in to change notification settings - Fork 6
drpcmux: add support for server interceptors #10
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| package drpcmux | ||
|
|
||
| import ( | ||
| "context" | ||
|
|
||
| "storj.io/drpc" | ||
| ) | ||
|
|
||
| // UnaryHandler defines the handler for the unary RPC. | ||
| type UnaryHandler func(ctx context.Context, in interface{}) (out interface{}, err error) | ||
|
|
||
| // UnaryServerInterceptor defines the server side interceptor for unary RPC. | ||
| type UnaryServerInterceptor func( | ||
| ctx context.Context, req interface{}, rpc string, handler UnaryHandler) (out interface{}, err error) | ||
|
|
||
| func chainUnaryInterceptors(interceptors []UnaryServerInterceptor) UnaryServerInterceptor { | ||
| switch n := len(interceptors); n { | ||
| case 0: | ||
| return nil | ||
| case 1: | ||
| return interceptors[0] | ||
| default: | ||
| return func(ctx context.Context, req interface{}, rpc string, handler UnaryHandler) ( | ||
| out interface{}, err error, | ||
| ) { | ||
| return interceptors[0]( | ||
| ctx, req, rpc, getChainedUnaryHandler(interceptors, 1, rpc, handler), | ||
| ) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| func getChainedUnaryHandler( | ||
| interceptors []UnaryServerInterceptor, currIdx int, rpc string, handler UnaryHandler, | ||
| ) UnaryHandler { | ||
| if currIdx == len(interceptors) { | ||
| return handler | ||
| } | ||
| return func(ctx context.Context, in interface{}) (out interface{}, err error) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about extracting this into
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's a bit more complicated. We're not just adapting the interceptor as a handler; we're also capturing arguments from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, you are right. I would suggest adding a comment on what that code is meant to do for future reference. |
||
| return interceptors[currIdx]( | ||
| ctx, in, rpc, getChainedUnaryHandler(interceptors, currIdx+1, rpc, handler), | ||
| ) | ||
| } | ||
| } | ||
|
|
||
| // StreamHandler defines the handler for the stream RPC. | ||
| type StreamHandler func(ctx context.Context, in drpc.Stream) (out interface{}, err error) | ||
|
|
||
| // StreamServerInterceptor defines a server side interceptor for unary RPC. | ||
| type StreamServerInterceptor func( | ||
| ctx context.Context, stream drpc.Stream, rpc string, handler StreamHandler) (out interface{}, err error) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Like we discussed before,
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm in favor of adding this, but I'm waiting to come across any use case where we need more than an RPC string. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not necessarily suggesting to block on this but IMO interfaces should also help with future needs. I'm fine with the current approach and revisit it if needed. |
||
|
|
||
| func chainStreamInterceptors(interceptors []StreamServerInterceptor) StreamServerInterceptor { | ||
| switch n := len(interceptors); n { | ||
| case 0: | ||
| return nil | ||
| case 1: | ||
| return interceptors[0] | ||
| default: | ||
| return func(ctx context.Context, stream drpc.Stream, rpc string, handler StreamHandler) ( | ||
| out interface{}, err error, | ||
| ) { | ||
| return interceptors[0]( | ||
| ctx, stream, rpc, getChainedStreamHandler(interceptors, 1, rpc, handler), | ||
| ) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| func getChainedStreamHandler( | ||
| interceptors []StreamServerInterceptor, currIdx int, rpc string, handler StreamHandler, | ||
| ) StreamHandler { | ||
| if currIdx == len(interceptors) { | ||
| return handler | ||
| } | ||
| return func(ctx context.Context, in drpc.Stream) (out interface{}, err error) { | ||
| return interceptors[currIdx]( | ||
| ctx, in, rpc, getChainedStreamHandler(interceptors, currIdx+1, rpc, handler), | ||
| ) | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add comments and contract for the interceptors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done