Defer handling onSuccess for large REST payloads

If an API returns a very large response, the parseJson call can take
75ms - 200ms to complete. Detect stalls greater than 75ms and defer
the onSuccess() handling to the next event loop so it isn't as
noticeable to the user.

Change-Id: Icc904f0c0e42b45771d5c3b003e89f845dbfb038
This commit is contained in:
Colby Ranger 2014-01-03 08:40:06 -08:00
parent 23dc4d1bdc
commit 784a5b30a0

View File

@ -23,6 +23,7 @@ import com.google.gerrit.client.Gerrit;
import com.google.gerrit.client.RpcStatus; import com.google.gerrit.client.RpcStatus;
import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject; import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.http.client.Request; import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder; import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestBuilder.Method; import com.google.gwt.http.client.RequestBuilder.Method;
@ -124,7 +125,8 @@ public class RestApi {
} }
} else if (200 <= status && status < 300) { } else if (200 <= status && status < 300) {
T data; long start = System.currentTimeMillis();
final T data;
if (isTextBody(res)) { if (isTextBody(res)) {
data = NativeString.wrap(res.getText()).cast(); data = NativeString.wrap(res.getText()).cast();
} else if (isJsonBody(res)) { } else if (isJsonBody(res)) {
@ -149,14 +151,25 @@ public class RestApi {
return; return;
} }
try { Scheduler.ScheduledCommand cmd = new Scheduler.ScheduledCommand() {
cb.onSuccess(data); @Override
} finally { public void execute() {
if (!background) { try {
RpcStatus.INSTANCE.onRpcComplete(); cb.onSuccess(data);
} finally {
if (!background) {
RpcStatus.INSTANCE.onRpcComplete();
}
}
} }
} };
// Defer handling the response if the parse took a while.
if ((System.currentTimeMillis() - start) > 75) {
Scheduler.get().scheduleDeferred(cmd);
} else {
cmd.execute();
}
} else { } else {
String msg; String msg;
if (isTextBody(res)) { if (isTextBody(res)) {