mirror of https://github.com/grpc/grpc-java.git
Force the immediate release of reference counted resources on AppEngine
to avoid executors backed by request-scoped threads from becoming zombies See https://cloud.google.com/appengine/docs/java/javadoc/com/google/appengine/api/ThreadManager.html#currentRequestThreadFactory--
This commit is contained in:
parent
3a13aa5665
commit
e276359f0e
|
|
@ -141,27 +141,35 @@ public final class SharedResourceHolder {
|
||||||
Preconditions.checkState(cached.refcount > 0, "Refcount has already reached zero");
|
Preconditions.checkState(cached.refcount > 0, "Refcount has already reached zero");
|
||||||
cached.refcount--;
|
cached.refcount--;
|
||||||
if (cached.refcount == 0) {
|
if (cached.refcount == 0) {
|
||||||
Preconditions.checkState(cached.destroyTask == null, "Destroy task already scheduled");
|
if (GrpcUtil.IS_RESTRICTED_APPENGINE) {
|
||||||
// Schedule a delayed task to destroy the resource.
|
// AppEngine must immediately release shared resources, particularly executors
|
||||||
if (destroyer == null) {
|
// which could retain request-scoped threads which become zombies after the request
|
||||||
destroyer = destroyerFactory.createScheduledExecutor();
|
// completes.
|
||||||
}
|
resource.close(instance);
|
||||||
cached.destroyTask = destroyer.schedule(new LogExceptionRunnable(new Runnable() {
|
instances.remove(resource);
|
||||||
@Override
|
} else {
|
||||||
public void run() {
|
Preconditions.checkState(cached.destroyTask == null, "Destroy task already scheduled");
|
||||||
synchronized (SharedResourceHolder.this) {
|
// Schedule a delayed task to destroy the resource.
|
||||||
// Refcount may have gone up since the task was scheduled. Re-check it.
|
if (destroyer == null) {
|
||||||
if (cached.refcount == 0) {
|
destroyer = destroyerFactory.createScheduledExecutor();
|
||||||
resource.close(instance);
|
}
|
||||||
instances.remove(resource);
|
cached.destroyTask = destroyer.schedule(new LogExceptionRunnable(new Runnable() {
|
||||||
if (instances.isEmpty()) {
|
@Override
|
||||||
destroyer.shutdown();
|
public void run() {
|
||||||
destroyer = null;
|
synchronized (SharedResourceHolder.this) {
|
||||||
|
// Refcount may have gone up since the task was scheduled. Re-check it.
|
||||||
|
if (cached.refcount == 0) {
|
||||||
|
resource.close(instance);
|
||||||
|
instances.remove(resource);
|
||||||
|
if (instances.isEmpty()) {
|
||||||
|
destroyer.shutdown();
|
||||||
|
destroyer = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}), DESTROY_DELAY_SECONDS, TimeUnit.SECONDS);
|
||||||
}), DESTROY_DELAY_SECONDS, TimeUnit.SECONDS);
|
}
|
||||||
}
|
}
|
||||||
// Always returning null
|
// Always returning null
|
||||||
return null;
|
return null;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue