Revision: 8825
Author: [email protected]
Date: Mon Sep 20 10:54:28 2010
Log: Allow RPC stats system extensions.
This patch allows for the extension of the RPC stats system by "moving" the
stats methods into an object, making them non-static. This would allow
application developers to extend the ProxyCreator to use a different
implementation of the stats methods.
Review at http://gwt-code-reviews.appspot.com/751801
Review by: [email protected]
http://code.google.com/p/google-web-toolkit/source/detail?r=8825
Added:
/trunk/user/src/com/google/gwt/user/client/rpc/impl/RpcStatsContext.java
Modified:
/trunk/tools/api-checker/config/gwt20_21userApi.conf
/trunk/user/src/com/google/gwt/rpc/client/impl/RpcCallbackAdapter.java
/trunk/user/src/com/google/gwt/rpc/client/impl/RpcServiceProxy.java
/trunk/user/src/com/google/gwt/user/client/rpc/impl/RemoteServiceProxy.java
/trunk/user/src/com/google/gwt/user/client/rpc/impl/RequestCallbackAdapter.java
/trunk/user/src/com/google/gwt/user/rebind/rpc/ProxyCreator.java
=======================================
--- /dev/null
+++
/trunk/user/src/com/google/gwt/user/client/rpc/impl/RpcStatsContext.java
Mon Sep 20 10:54:28 2010
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2010 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may
not
+ * use this file except in compliance with the License. You may obtain a
copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
under
+ * the License.
+ */
+package com.google.gwt.user.client.rpc.impl;
+
+import com.google.gwt.core.client.JavaScriptObject;
+
+/**
+ * Sends stats events for RPC calls.
+ */
+public class RpcStatsContext {
+ /**
+ * A global counter/generator for ids to track any given request.
+ */
+ private static int requestIdCounter;
+
+ static int getNextRequestId() {
+ return requestIdCounter++;
+ }
+
+ static int getLastRequestId() {
+ return requestIdCounter;
+ }
+
+ private int requestId;
+
+ public RpcStatsContext() {
+ this(getNextRequestId());
+ }
+
+ public RpcStatsContext(int requestId) {
+ this.requestId = requestId;
+ }
+
+ public native JavaScriptObject bytesStat(String method, int bytes,
String eventType) /*-{
+ var stat =
[email protected]::timeStat(Ljava/lang/String;Ljava/lang/String;)(method,
eventType);
+ stat.bytes = bytes;
+ return stat;
+ }-*/;
+
+ public int getRequestId() {
+ return requestId;
+ }
+
+ /**
+ * Indicates if RPC statistics should be gathered.
+ */
+ public native boolean isStatsAvailable() /*-{
+ return !!$stats;
+ }-*/;
+
+ /**
+ * Always use this as {...@link #isStatsAvailable()} &&
+ * {...@link #stats(JavaScriptObject)}.
+ */
+ public native boolean stats(JavaScriptObject data) /*-{
+ return $stats(data);
+ }-*/;
+
+ public native JavaScriptObject timeStat(String method, String eventType)
/*-{
+ return {
+ moduleName: @com.google.gwt.core.client.GWT::getModuleName()(),
+ sessionId: $sessionId,
+ subSystem: 'rpc',
+ evtGroup:
[email protected]::requestId,
+ method: method,
+ millis: (new Date()).getTime(),
+ type: eventType
+ };
+ }-*/;
+
+ public JavaScriptObject timeStat(String method, Object result, String
eventType) {
+ return timeStat(method, eventType);
+ }
+}
=======================================
--- /trunk/tools/api-checker/config/gwt20_21userApi.conf Mon Sep 20
07:10:58 2010
+++ /trunk/tools/api-checker/config/gwt20_21userApi.conf Mon Sep 20
10:54:28 2010
@@ -166,3 +166,10 @@
com.google.gwt.i18n.client.CurrencyList::namesMap MISSING
com.google.gwt.i18n.client.CurrencyList::overrideCurrencyMap(Lcom/google/gwt/core/client/JavaScriptObject;)
MISSING
com.google.gwt.i18n.client.CurrencyList::overrideNamesMap(Lcom/google/gwt/core/client/JavaScriptObject;)
MISSING
+
+# Introduction of RpcStatsContext, which is now passed instead of the
integer ids.
+com.google.gwt.rpc.client.impl.RpcCallbackAdapter::RpcCallbackAdapter(Lcom/google/gwt/user/client/rpc/SerializationStreamFactory;Ljava/lang/String;ILcom/google/gwt/user/client/rpc/AsyncCallback;)
MISSING
+com.google.gwt.rpc.client.impl.RpcServiceProxy::doInvoke(Lcom/google/gwt/user/client/rpc/impl/RequestCallbackAdapter$ResponseReader;Ljava/lang/String;ILjava/lang/String;Lcom/google/gwt/user/client/rpc/AsyncCallback;)
MISSING
+com.google.gwt.rpc.client.impl.RpcServiceProxy::doPrepareRequestBuilder(Lcom/google/gwt/user/client/rpc/impl/RequestCallbackAdapter$ResponseReader;Ljava/lang/String;ILjava/lang/String;Lcom/google/gwt/user/client/rpc/AsyncCallback;)
MISSING
+com.google.gwt.rpc.client.impl.RpcServiceProxy::doCreateRequestCallback(Lcom/google/gwt/user/client/rpc/impl/RequestCallbackAdapter$ResponseReader;Ljava/lang/String;ILcom/google/gwt/user/client/rpc/AsyncCallback;)
MISSING
+
=======================================
--- /trunk/user/src/com/google/gwt/rpc/client/impl/RpcCallbackAdapter.java
Wed Oct 28 09:10:53 2009
+++ /trunk/user/src/com/google/gwt/rpc/client/impl/RpcCallbackAdapter.java
Mon Sep 20 10:54:28 2010
@@ -24,7 +24,7 @@
import com.google.gwt.user.client.rpc.SerializationException;
import com.google.gwt.user.client.rpc.SerializationStreamFactory;
import com.google.gwt.user.client.rpc.StatusCodeException;
-import com.google.gwt.user.client.rpc.impl.RemoteServiceProxy;
+import com.google.gwt.user.client.rpc.impl.RpcStatsContext;
/**
* Adapter from a {...@link RequestCallback} interface to an {...@link
AsyncCallback}
@@ -49,19 +49,19 @@
/**
* Used for stats recording.
*/
- private final int requestId;
+ private final RpcStatsContext statsContext;
private final SerializationStreamFactory streamFactory;
public RpcCallbackAdapter(SerializationStreamFactory streamFactory,
- String methodName, int requestId, AsyncCallback<T> callback) {
+ String methodName, RpcStatsContext statsContext, AsyncCallback<T>
callback) {
assert (streamFactory != null);
assert (callback != null);
this.streamFactory = streamFactory;
this.callback = callback;
this.methodName = methodName;
- this.requestId = requestId;
+ this.statsContext = statsContext;
}
public void onError(Request request, Throwable exception) {
@@ -75,9 +75,9 @@
try {
String encodedResponse = response.getText();
int statusCode = response.getStatusCode();
- boolean toss = RemoteServiceProxy.isStatsAvailable()
- &&
RemoteServiceProxy.stats(RemoteServiceProxy.bytesStat(methodName,
- requestId, encodedResponse.length(), "responseReceived"));
+ boolean toss = statsContext.isStatsAvailable()
+ && statsContext.stats(
+ statsContext.bytesStat(methodName,
encodedResponse.length(), "responseReceived"));
if (statusCode != Response.SC_OK) {
caught = new StatusCodeException(statusCode, encodedResponse);
@@ -95,9 +95,8 @@
} catch (Throwable e) {
caught = e;
} finally {
- boolean toss = RemoteServiceProxy.isStatsAvailable()
- &&
RemoteServiceProxy.stats(RemoteServiceProxy.timeStat(methodName,
- requestId, "responseDeserialized"));
+ boolean toss = statsContext.isStatsAvailable()
+ &&
statsContext.stats(statsContext.timeStat(methodName, "responseDeserialized"));
}
try {
@@ -107,9 +106,8 @@
callback.onFailure(caught);
}
} finally {
- boolean toss = RemoteServiceProxy.isStatsAvailable()
- &&
RemoteServiceProxy.stats(RemoteServiceProxy.timeStat(methodName,
- requestId, "end"));
+ boolean toss = statsContext.isStatsAvailable()
+ && statsContext.stats(statsContext.timeStat(methodName, "end"));
}
}
}
=======================================
--- /trunk/user/src/com/google/gwt/rpc/client/impl/RpcServiceProxy.java Wed
Dec 2 15:06:59 2009
+++ /trunk/user/src/com/google/gwt/rpc/client/impl/RpcServiceProxy.java Mon
Sep 20 10:54:28 2010
@@ -23,6 +23,7 @@
import com.google.gwt.user.client.rpc.SerializationStreamWriter;
import com.google.gwt.user.client.rpc.impl.RemoteServiceProxy;
import
com.google.gwt.user.client.rpc.impl.RequestCallbackAdapter.ResponseReader;
+import com.google.gwt.user.client.rpc.impl.RpcStatsContext;
/**
* The base type for RPC proxies.
@@ -50,9 +51,9 @@
@Override
protected <T> RequestCallback doCreateRequestCallback(
- ResponseReader responseReader, String methodName, int
invocationCount,
+ ResponseReader responseReader, String methodName, RpcStatsContext
statsContext,
AsyncCallback<T> callback) {
- return new RpcCallbackAdapter<T>(this, methodName, invocationCount,
+ return new RpcCallbackAdapter<T>(this, methodName, statsContext,
callback);
}
=======================================
---
/trunk/user/src/com/google/gwt/user/client/rpc/impl/RemoteServiceProxy.java
Wed Dec 2 14:20:27 2009
+++
/trunk/user/src/com/google/gwt/user/client/rpc/impl/RemoteServiceProxy.java
Mon Sep 20 10:54:28 2010
@@ -45,47 +45,50 @@
private static final String RPC_CONTENT_TYPE = "text/x-gwt-rpc;
charset=utf-8";
/**
- * A global id to track any given request.
+ * @deprecated use {...@link RpcStatsContext}.
*/
- private static int requestId;
-
- public static native JavaScriptObject bytesStat(String method, int count,
- int bytes, String eventType) /*-{
- var stat =
@com.google.gwt.user.client.rpc.impl.RemoteServiceProxy::timeStat(Ljava/lang/String;ILjava/lang/String;)(method,
count, eventType);
- stat.bytes = bytes;
- return stat;
- }-*/;
+ @Deprecated
+ public static JavaScriptObject bytesStat(String method, int count,
+ int bytes, String eventType) {
+ return new RpcStatsContext(count).bytesStat(method, bytes, eventType);
+ }
/**
* Indicates if RPC statistics should be gathered.
+ *
+ * @deprecated use {...@link RpcStatsContext}.
*/
- public static native boolean isStatsAvailable() /*-{
- return !!$stats;
- }-*/;
+ @Deprecated
+ public static boolean isStatsAvailable() {
+ return new RpcStatsContext(0).isStatsAvailable();
+ }
/**
* Always use this as {...@link #isStatsAvailable()} &&
* {...@link #stats(JavaScriptObject)}.
+ *
+ * @deprecated use {link RpcStatsContext}.
*/
- public static native boolean stats(JavaScriptObject data) /*-{
- return $stats(data);
- }-*/;
-
- public static native JavaScriptObject timeStat(String method, int count,
- String eventType) /*-{
- return {
- moduleName: @com.google.gwt.core.client.GWT::getModuleName()(),
- sessionId: $sessionId,
- subSystem: 'rpc',
- evtGroup: count,
- method: method,
- millis: (new Date()).getTime(),
- type: eventType
- };
- }-*/;
-
+ @Deprecated
+ public static boolean stats(JavaScriptObject data) {
+ return new RpcStatsContext(0).stats(data);
+ }
+
+ /**
+ * @deprecated use {...@link RpcStatsContext}.
+ */
+ @Deprecated
+ public static JavaScriptObject timeStat(String method, int count,
+ String eventType) {
+ return new RpcStatsContext(count).timeStat(method, eventType);
+ }
+
+ /**
+ * @deprected use {...@link RpcStatsContext}.
+ */
+ @Deprecated
protected static int getNextRequestId() {
- return requestId++;
+ return RpcStatsContext.getNextRequestId();
}
/**
@@ -93,7 +96,7 @@
*/
@Deprecated
protected static int getRequestId() {
- return requestId;
+ return RpcStatsContext.getLastRequestId();
}
/**
@@ -236,9 +239,9 @@
}
protected <T> RequestCallback doCreateRequestCallback(
- ResponseReader responseReader, String methodName, int
invocationCount,
+ ResponseReader responseReader, String methodName, RpcStatsContext
statsContext,
AsyncCallback<T> callback) {
- return new RequestCallbackAdapter<T>(this, methodName, invocationCount,
+ return new RequestCallbackAdapter<T>(this, methodName, statsContext,
callback, responseReader);
}
@@ -256,11 +259,11 @@
* @return a {...@link Request} object that can be used to track the request
*/
protected <T> Request doInvoke(ResponseReader responseReader,
- String methodName, int invocationCount, String requestData,
+ String methodName, RpcStatsContext statsContext, String requestData,
AsyncCallback<T> callback) {
RequestBuilder rb = doPrepareRequestBuilderImpl(responseReader,
methodName,
- invocationCount, requestData, callback);
+ statsContext, requestData, callback);
try {
return rb.send();
@@ -270,10 +273,9 @@
ex);
callback.onFailure(iex);
} finally {
- if (RemoteServiceProxy.isStatsAvailable()
- &&
RemoteServiceProxy.stats(RemoteServiceProxy.bytesStat(methodName,
- invocationCount, requestData.length(), "requestSent"))) {
- }
+ boolean toss = statsContext.isStatsAvailable() &&
+ statsContext.stats(statsContext.bytesStat(methodName,
requestData.length(),
+ "requestSent"));
}
return null;
}
@@ -293,11 +295,11 @@
* {...@link RequestBuilder#send()} method invoked.
*/
protected <T> RequestBuilder doPrepareRequestBuilder(
- ResponseReader responseReader, String methodName, int
invocationCount,
+ ResponseReader responseReader, String methodName, RpcStatsContext
statsContext,
String requestData, AsyncCallback<T> callback) {
RequestBuilder rb = doPrepareRequestBuilderImpl(responseReader,
methodName,
- invocationCount, requestData, callback);
+ statsContext, requestData, callback);
return rb;
}
@@ -316,7 +318,7 @@
* {...@link RequestBuilder#send()} method invoked.
*/
private <T> RequestBuilder doPrepareRequestBuilderImpl(
- ResponseReader responseReader, String methodName, int
invocationCount,
+ ResponseReader responseReader, String methodName, RpcStatsContext
statsContext,
String requestData, AsyncCallback<T> callback) {
if (getServiceEntryPoint() == null) {
@@ -324,7 +326,7 @@
}
RequestCallback responseHandler =
doCreateRequestCallback(responseReader,
- methodName, invocationCount, callback);
+ methodName, statsContext, callback);
ensureRpcRequestBuilder();
@@ -332,7 +334,7 @@
rpcRequestBuilder.setCallback(responseHandler);
rpcRequestBuilder.setContentType(RPC_CONTENT_TYPE);
rpcRequestBuilder.setRequestData(requestData);
- rpcRequestBuilder.setRequestId(invocationCount);
+ rpcRequestBuilder.setRequestId(statsContext.getRequestId());
return rpcRequestBuilder.finish();
}
=======================================
---
/trunk/user/src/com/google/gwt/user/client/rpc/impl/RequestCallbackAdapter.java
Fri Apr 3 09:36:11 2009
+++
/trunk/user/src/com/google/gwt/user/client/rpc/impl/RequestCallbackAdapter.java
Mon Sep 20 10:54:28 2010
@@ -145,7 +145,7 @@
/**
* Used for stats recording.
*/
- private final int requestId;
+ private final RpcStatsContext statsContext;
/**
* Instance which will read the expected return type out of the
@@ -160,7 +160,7 @@
private final SerializationStreamFactory streamFactory;
public RequestCallbackAdapter(SerializationStreamFactory streamFactory,
- String methodName, int requestId, AsyncCallback<T> callback,
+ String methodName, RpcStatsContext statsContext, AsyncCallback<T>
callback,
ResponseReader responseReader) {
assert (streamFactory != null);
assert (callback != null);
@@ -169,7 +169,7 @@
this.streamFactory = streamFactory;
this.callback = callback;
this.methodName = methodName;
- this.requestId = requestId;
+ this.statsContext = statsContext;
this.responseReader = responseReader;
}
@@ -184,9 +184,9 @@
try {
String encodedResponse = response.getText();
int statusCode = response.getStatusCode();
- boolean toss = RemoteServiceProxy.isStatsAvailable()
- &&
RemoteServiceProxy.stats(RemoteServiceProxy.bytesStat(methodName,
- requestId, encodedResponse.length(), "responseReceived"));
+ boolean toss = statsContext.isStatsAvailable()
+ && statsContext.stats(
+ statsContext.bytesStat(methodName,
encodedResponse.length(), "responseReceived"));
if (statusCode != Response.SC_OK) {
caught = new StatusCodeException(statusCode, encodedResponse);
@@ -206,9 +206,8 @@
} catch (Throwable e) {
caught = e;
} finally {
- boolean toss = RemoteServiceProxy.isStatsAvailable()
- && RemoteServiceProxy.stats(RemoteServiceProxy.timeStat(
- methodName, requestId, "responseDeserialized"));
+ boolean toss = statsContext.isStatsAvailable()
+ &&
statsContext.stats(statsContext.timeStat(methodName, "responseDeserialized"));
}
try {
@@ -218,9 +217,9 @@
callback.onFailure(caught);
}
} finally {
- boolean toss = RemoteServiceProxy.isStatsAvailable()
- && RemoteServiceProxy.stats(RemoteServiceProxy.timeStat(
- methodName, requestId, "end"));
+ Object returned = (caught == null) ? result : caught;
+ boolean toss = statsContext.isStatsAvailable()
+ && statsContext.stats(statsContext.timeStat(methodName,
returned, "end"));
}
}
}
=======================================
--- /trunk/user/src/com/google/gwt/user/rebind/rpc/ProxyCreator.java Thu
Sep 16 12:36:47 2010
+++ /trunk/user/src/com/google/gwt/user/rebind/rpc/ProxyCreator.java Mon
Sep 20 10:54:28 2010
@@ -48,6 +48,7 @@
import com.google.gwt.user.client.rpc.impl.FailingRequestBuilder;
import com.google.gwt.user.client.rpc.impl.RemoteServiceProxy;
import
com.google.gwt.user.client.rpc.impl.RequestCallbackAdapter.ResponseReader;
+import com.google.gwt.user.client.rpc.impl.RpcStatsContext;
import com.google.gwt.user.linker.rpc.RpcLogArtifact;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;
@@ -442,15 +443,13 @@
w.println(") {");
w.indent();
- String requestIdName = nameFactory.createName("requestId");
- w.println("int " + requestIdName + " = getNextRequestId();");
+ String statsContextName = nameFactory.createName("statsContext");
+ generateRpcStatsContext(w, syncMethod, asyncMethod, statsContextName);
String statsMethodExpr = getProxySimpleName() + "." +
syncMethod.getName();
String tossName = nameFactory.createName("toss");
- w.println("boolean " + tossName + " = isStatsAvailable() && stats("
- + "timeStat(\"" + statsMethodExpr + "\", " + requestIdName
- + ", \"begin\"));");
-
+ w.println("boolean %s = %s.isStatsAvailable()
&& %s.stats(%s.timeStat(\"%s\", \"begin\"));",
+ tossName, statsContextName, statsContextName, statsContextName,
statsMethodExpr);
w.print(SerializationStreamWriter.class.getSimpleName());
w.print(" ");
String streamWriterName = nameFactory.createName("streamWriter");
@@ -490,9 +489,9 @@
w.println("String " + payloadName + " = " + streamWriterName
+ ".toString();");
- w.println(tossName + " = isStatsAvailable() && stats(" + "timeStat(\""
- + statsMethodExpr + "\", " + requestIdName
- + ", \"requestSerialized\"));");
+ w.println(tossName + " = " + statsContextName + ".isStatsAvailable()
&& "
+ + statsContextName + ".stats(" + statsContextName + ".timeStat(\""
+ + statsMethodExpr + "\", \"requestSerialized\"));");
/*
* Depending on the return type for the async method, return a
@@ -517,7 +516,7 @@
JType returnType = syncMethod.getReturnType();
w.print("ResponseReader." + getResponseReaderFor(returnType).name());
w.println(", \"" + getProxySimpleName() + "." + syncMethod.getName()
- + "\", " + requestIdName + ", " + payloadName + ", " + callbackName
+ + "\", " + statsContextName + ", " + payloadName + ", " +
callbackName
+ ");");
w.outdent();
@@ -578,6 +577,11 @@
generateProxyMethod(w, serializableTypeOracle, syncMethod,
asyncMethod);
}
}
+
+ protected void generateRpcStatsContext(SourceWriter w, JMethod
syncMethod,
+ JMethod asyncMethod, String statsContextName) {
+ w.println("RpcStatsContext " + statsContextName + " = new
RpcStatsContext();");
+ }
protected void generateStreamWriterOverride(SourceWriter srcWriter) {
srcWriter.println("@Override");
@@ -802,7 +806,8 @@
SerializationStreamWriter.class.getCanonicalName(),
GWT.class.getCanonicalName(),
ResponseReader.class.getCanonicalName(),
SerializationException.class.getCanonicalName(),
- Impl.class.getCanonicalName()};
+ Impl.class.getCanonicalName(),
+ RpcStatsContext.class.getCanonicalName()};
for (String imp : imports) {
composerFactory.addImport(imp);
}
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors