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

A question about the solution for Context / Scoped Beans #374

Closed
ChaselX opened this issue Jun 23, 2020 · 1 comment
Closed

A question about the solution for Context / Scoped Beans #374

ChaselX opened this issue Jun 23, 2020 · 1 comment
Labels
feedback required Information are missing or feedback for suggestions is requested question A question about this library or its usage

Comments

@ChaselX
Copy link
Contributor

ChaselX commented Jun 23, 2020

The context

As the doc said "In grpc-java different steps in the message delivery / request process can and will run in different threads. This is
not only but especially relevant for streaming calls. Avoid using ThreadLocals inside your ServerInterceptors and
grpc service method implementations (in the entire grpc context). When it comes down to it, the preparation phase, every
single message and the completion phase might run in different threads. If you wish to store data for the duration of
the session, do so either using grpc's Context or grpcRequest scoped beans."

So you defined the GrpcRequestScope.

The question

But I look up the source code, The Only Implement for io.grpc.Context.Storage is io.grpc.ThreadLocalContextStorage. This is also based on ThreadLocal.

So how can it useful for ** different steps use different threads** ??

If this question could be picked , I will be very grateful. Thank you

@ChaselX ChaselX added the question A question about this library or its usage label Jun 23, 2020
@ChaselX ChaselX changed the title The solution for Context / Scoped Beans A question about the solution for Context / Scoped Beans Jun 23, 2020
@ST-DDT
Copy link
Collaborator

ST-DDT commented Jun 24, 2020

You can theoretically use ThreadLocals while a single Message is processed.

  • If you have an unary or server streaming call, you can use thread locals throughout ServerInterceptor#interceptCall, ServerCallListener#onMesssage, ServerCallListener#onHalfClose and your entire method implementation.
  • If you have a client or bi-directional streaming call, then you can use a thread local in ServerCallListener#interceptCall and your main implementation of your method implementation. You can use a separate one for ServerInterceptor#onMesssage and the StreamObserver#onNext returned by your method implementation. However, you cannot use them across each other.

The pairs of working methods might change in a future release (or might have already) , so be careful to do it "right".

The following implementation uses spring security's (ThreadLocal) storage to set the authentication, please note that the authentication is set before each method (ServerCallListener + ServerInterceptor) call and removed afterwards:

DefaultAuthenticatingServerInterceptor
AbstractAuthenticatingServerCallListener

The GrpcContext works in a similar fashion. The Thread local is populated right before each step and immediately cleared afterwards,

WARNING: Do not try to use Thread-Locals across these borders or you end up in something, that "works" in low load environments and fails in production.

I explicitly added a test to this project to ensure that everything works in a concurrent environment.
ConcurrentSecurityTest

If you aren't careful you end up like the examples mentioned in this comment:
LogNet/grpc-spring-boot-starter#61 (comment)

Does this solve your question?

@ST-DDT ST-DDT added the feedback required Information are missing or feedback for suggestions is requested label Jun 24, 2020
@ST-DDT ST-DDT closed this as completed Jul 13, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feedback required Information are missing or feedback for suggestions is requested question A question about this library or its usage
Projects
None yet
Development

No branches or pull requests

2 participants