-
Notifications
You must be signed in to change notification settings - Fork 3.8k
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
Sending Grpc Request in Appengine Java 8 Standard Environment Could Fail #3296
Comments
I believe @cmaan had the same issue but with the Spanner client if that sheds any light on it |
@neozwu Can you clarify when it is okay to start a new thread? |
@carl-mastrangelo there are more discussions here. It seems to me grpc handles GAE J7 request threads specifically in order to avoid zombie threads. The same thing should apply to J8. However, the |
@neozwu I don't understand. All gRPC threads are created with Daemon=true. Where do you see that not being the case? |
@carl-mastrangelo , thanks for following up. I suspect |
@carl-mastrangelo would you be able to respond to @neozwu 's last comment? |
I thought the point of GAE J8 was that it didn't have all the painful restrictions, which is why IS_RESTRICTED_APPENGINE is stuck on J7. OkHttp will use a worse TLS suite (rand I think?) on J7 which we don't want to keep doing on j8. Making IS_RESTRICTED_APPENGINE true on j8 would be conflating grpc thread behavior with grpc TLS behavior. No one has said specifically why creating a thread doesn't work on G8, and I don't really have time to walk all the previous discussions. Why was an NPE raised? What was actually null? Why isn't this filed under app engine instead of gRPC? |
@rrch would you be able to shed light on why GAE raises this? |
Do we need a new configuration, The problem is more fundamentally the thread factory that is chosen. On both G7 and G8, the thread factory chosen while in the app engine request thread has restrictions around the threads it creates (e.g. you can't create threads from it while not in an app engine request thread). So, trying to use that thread factory in other contexts will cause an NPE (internal detail - maybe another exception is more appropriate, but regardless, a different exception would probably be explicitly thrown if the NPE itself was fixed.) |
The "current request thread factory" only works in the context of a request. This is currently true for all App Engine APIs in Java 8: if you invoke them from a thread that is not associated with a request, they will fail. In several other places we've improved the message associated with the exception to make the problem clearer, I'll file a bug to do the same for thread factories. |
I had mentioned that maybe the problem is we are using However, I also heard that you can't do AppEngine API calls from "normal" threads. That seems like that would be a be a problem for 1) the callback executor and 2) auth. |
While the code had correctly determined full threads were available, the call to MoreExecutors returned a request thread factory, which has limitations. Note that Async stub users may not be able to call GAE APIs in callbacks. This is because the threads aren't request threads. They can override the individual call's executor with com.google.appengine.api.ThreadManager.currentRequestThreadFactory() in an interceptor via callOptions.withExecutor(). Fixes grpc#3296
While the code had correctly determined full threads were available, the call to MoreExecutors returned a request thread factory, which has limitations. Note that Async stub users may not be able to call GAE APIs in callbacks. This is because the threads aren't request threads. They can override the individual call's executor with com.google.appengine.api.ThreadManager.currentRequestThreadFactory() in an interceptor via callOptions.withExecutor(). Fixes #3296
While the code had correctly determined full threads were available, the call to MoreExecutors returned a request thread factory, which has limitations. Note that Async stub users may not be able to call GAE APIs in callbacks. This is because the threads aren't request threads. They can override the individual call's executor with com.google.appengine.api.ThreadManager.currentRequestThreadFactory() in an interceptor via callOptions.withExecutor(). Fixes grpc#3296
While the code had correctly determined full threads were available, the call to MoreExecutors returned a request thread factory, which has limitations. Note that Async stub users may not be able to call GAE APIs in callbacks. This is because the threads aren't request threads. They can override the individual call's executor with com.google.appengine.api.ThreadManager.currentRequestThreadFactory() in an interceptor via callOptions.withExecutor(). Fixes #3296
What version of gRPC are you using?
1.4.0
What JVM are you using (
java -version
)?Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
Google-cloud-java has received issues (googleapis/google-cloud-java#2150, googleapis/google-cloud-java#2275) regarding sending grpc reqeust in appengine (specifically, using google-cloud-java Pub/Sub client library). When initiating grpc connection in appengine, grpc picks up
currentRequestThreadFactory
for its thread factory (https://github.com/grpc/grpc-java/blob/master/core/src/main/java/io/grpc/internal/GrpcUtil.java#L482). This could cause appengine runtime to throw NPE (see below for a typical stack trace). A hack to forcedefaultThreadFactory
to be used by Grpc seems to resolve this issue.Sending Grpc request within Appengine request thread seems to be a valid scenario. Grpc should support it.
/cc @jbaldassari @cmaan @jabubake @tcoffee-google @garrettjonesgoogle
The text was updated successfully, but these errors were encountered: