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()} &amp;&amp;
    * {...@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

Reply via email to