cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dk...@apache.org
Subject cxf git commit: Update the codahale metrics stuff to make it easier to add additional metrics associated with the message context.
Date Thu, 19 Mar 2015 17:18:59 GMT
Repository: cxf
Updated Branches:
  refs/heads/master 5fc6229a6 -> c5da4140d


Update the codahale metrics stuff to make it easier to add additional metrics associated with
the message context.


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/c5da4140
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/c5da4140
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/c5da4140

Branch: refs/heads/master
Commit: c5da4140da8fe63c4a10845b95258bbda9ab2058
Parents: 5fc6229
Author: Daniel Kulp <dkulp@apache.org>
Authored: Thu Mar 19 13:17:01 2015 -0400
Committer: Daniel Kulp <dkulp@apache.org>
Committed: Thu Mar 19 13:18:47 2015 -0400

----------------------------------------------------------------------
 .../codahale/CodahaleMetricsContext.java        | 109 +++++++++++
 .../cxf/management/codahale/MessageMetrics.java |  77 ++++++++
 .../apache/cxf/management/codahale/Metrics.java | 183 ++++++-------------
 .../cxf/management/codahale/MetricsContext.java |  47 +++++
 4 files changed, 286 insertions(+), 130 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/c5da4140/rt/management/src/main/java/org/apache/cxf/management/codahale/CodahaleMetricsContext.java
----------------------------------------------------------------------
diff --git a/rt/management/src/main/java/org/apache/cxf/management/codahale/CodahaleMetricsContext.java
b/rt/management/src/main/java/org/apache/cxf/management/codahale/CodahaleMetricsContext.java
new file mode 100644
index 0000000..9c23d75
--- /dev/null
+++ b/rt/management/src/main/java/org/apache/cxf/management/codahale/CodahaleMetricsContext.java
@@ -0,0 +1,109 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.cxf.management.codahale;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+import com.codahale.metrics.Counter;
+import com.codahale.metrics.Meter;
+import com.codahale.metrics.MetricRegistry;
+import com.codahale.metrics.Timer;
+
+import org.apache.cxf.message.FaultMode;
+
+/**
+ * 
+ */
+public class CodahaleMetricsContext implements MetricsContext, Closeable {
+    protected Counter inFlight;
+    protected Timer totals;
+    protected Timer uncheckedApplicationFaults;
+    protected Timer checkedApplicationFaults;
+    protected Timer runtimeFaults;
+    protected Timer logicalRuntimeFaults;
+    protected Meter incomingData;
+    protected Meter outgoingData;
+    
+    protected final String baseName;
+    protected final MetricRegistry registry;
+    
+    public CodahaleMetricsContext(String prefix, MetricRegistry registry) {
+        baseName = prefix;
+        this.registry = registry;
+        totals = registry.timer(baseName + "Attribute=Totals");
+        uncheckedApplicationFaults = registry.timer(baseName 
+                                                    + "Attribute=Unchecked Application Faults");
+        checkedApplicationFaults = registry.timer(baseName + "Attribute=Checked Application
Faults");
+        runtimeFaults = registry.timer(baseName + "Attribute=Runtime Faults");
+        logicalRuntimeFaults = registry.timer(baseName + "Attribute=Logical Runtime Faults");
+        inFlight = registry.counter(baseName + "Attribute=In Flight");
+        incomingData = registry.meter(baseName + "Attribute=Data Read");
+        outgoingData = registry.meter(baseName + "Attribute=Data Written");
+    }
+
+    @Override
+    public void close() throws IOException {
+        registry.remove(baseName + "Attribute=Totals");
+        registry.remove(baseName + "Attribute=Unchecked Application Faults");
+        registry.remove(baseName + "Attribute=Checked Application Faults");
+        registry.remove(baseName + "Attribute=Runtime Faults");
+        registry.remove(baseName + "Attribute=Logical Runtime Faults");
+        registry.remove(baseName + "Attribute=In Flight");
+        registry.remove(baseName + "Attribute=Data Read");
+        registry.remove(baseName + "Attribute=Data Written");
+    }
+
+    
+    public void start() {
+        inFlight.inc();
+    }
+    
+    public void stop(long timeInNS, long inSize, long outSize, FaultMode fm) {
+        totals.update(timeInNS, TimeUnit.NANOSECONDS);
+
+        if (inSize != -1) {
+            incomingData.mark(inSize);
+        }
+        if (outSize != -1) {
+            outgoingData.mark(outSize);
+        }
+        if (fm != null) {
+            switch (fm) {
+            case CHECKED_APPLICATION_FAULT:
+                checkedApplicationFaults.update(timeInNS,  TimeUnit.NANOSECONDS);
+                break;
+            case UNCHECKED_APPLICATION_FAULT:
+                uncheckedApplicationFaults.update(timeInNS,  TimeUnit.NANOSECONDS);
+                break;
+            case RUNTIME_FAULT:
+                runtimeFaults.update(timeInNS,  TimeUnit.NANOSECONDS);
+                break;
+            case LOGICAL_RUNTIME_FAULT:
+                logicalRuntimeFaults.update(timeInNS,  TimeUnit.NANOSECONDS);
+                break;
+            default:
+            }
+        }
+        inFlight.dec();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/c5da4140/rt/management/src/main/java/org/apache/cxf/management/codahale/MessageMetrics.java
----------------------------------------------------------------------
diff --git a/rt/management/src/main/java/org/apache/cxf/management/codahale/MessageMetrics.java
b/rt/management/src/main/java/org/apache/cxf/management/codahale/MessageMetrics.java
new file mode 100644
index 0000000..3f4845b
--- /dev/null
+++ b/rt/management/src/main/java/org/apache/cxf/management/codahale/MessageMetrics.java
@@ -0,0 +1,77 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.cxf.management.codahale;
+
+import java.util.Deque;
+import java.util.LinkedList;
+
+import org.apache.cxf.message.FaultMode;
+import org.apache.cxf.message.Message;
+
+/**
+ * 
+ */
+public class MessageMetrics {
+    Deque<MetricsContext> contexts = new LinkedList<MetricsContext>();
+    boolean started;
+    long startTime = -1;
+    
+    public MessageMetrics() {
+    }
+
+    public MessageMetrics addContext(MetricsContext ctx) {
+        contexts.addLast(ctx);
+        if (started) {
+            ctx.start();
+        }
+        return this;
+    }
+    
+    public void start() {
+        started = true;
+        startTime = System.nanoTime();
+        for (MetricsContext ctx : contexts) {
+            ctx.start();
+        }
+    }
+    
+    public void stop(Message m) {
+        started = false;
+        if (startTime == -1) {
+            return;
+        }
+        FaultMode fm = m.getExchange().get(FaultMode.class);       
+        CountingInputStream in = m.getExchange().get(CountingInputStream.class);
+        long inSize = -1;
+        long outSize = -1;
+        if (in != null) {
+            inSize = in.getCount();
+        }
+        CountingOutputStream out = m.getExchange().get(CountingOutputStream.class);
+        if (out != null) {
+            outSize = out.getCount();
+        }
+        long l = System.nanoTime() - startTime;
+        for (MetricsContext ctx : contexts) {
+            ctx.stop(l, inSize, outSize, fm);
+        }
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/c5da4140/rt/management/src/main/java/org/apache/cxf/management/codahale/Metrics.java
----------------------------------------------------------------------
diff --git a/rt/management/src/main/java/org/apache/cxf/management/codahale/Metrics.java b/rt/management/src/main/java/org/apache/cxf/management/codahale/Metrics.java
index 05830e1..666ba36 100644
--- a/rt/management/src/main/java/org/apache/cxf/management/codahale/Metrics.java
+++ b/rt/management/src/main/java/org/apache/cxf/management/codahale/Metrics.java
@@ -24,17 +24,13 @@ import java.io.Closeable;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
-import java.util.concurrent.TimeUnit;
 
 import javax.management.MalformedObjectNameException;
 import javax.management.ObjectName;
 
-import com.codahale.metrics.Counter;
 import com.codahale.metrics.JmxReporter;
-import com.codahale.metrics.Meter;
 import com.codahale.metrics.MetricRegistry;
 import com.codahale.metrics.ObjectNameFactory;
-import com.codahale.metrics.Timer;
 
 import org.apache.cxf.Bus;
 import org.apache.cxf.endpoint.Endpoint;
@@ -46,7 +42,6 @@ import org.apache.cxf.interceptor.ServiceInvokerInterceptor;
 import org.apache.cxf.management.InstrumentationManager;
 import org.apache.cxf.management.ManagementConstants;
 import org.apache.cxf.message.Exchange;
-import org.apache.cxf.message.FaultMode;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.message.MessageUtils;
 import org.apache.cxf.phase.AbstractPhaseInterceptor;
@@ -100,79 +95,44 @@ public class Metrics {
         ResponseTimeMessageInOneWayInterceptor oneway = new ResponseTimeMessageInOneWayInterceptor();
         ResponseTimeMessageOutInterceptor out = new ResponseTimeMessageOutInterceptor();
         CountingOutInterceptor countingOut = new CountingOutInterceptor();
-        //ResponseTimeMessageInvokerInterceptor invoker = new ResponseTimeMessageInvokerInterceptor();
         
         bus.getInInterceptors().add(in);
         bus.getInInterceptors().add(oneway);
+        bus.getInInterceptors().add(new ResponseTimeMessageInPreInvokeInterceptor());
         bus.getOutInterceptors().add(countingOut);
         bus.getOutInterceptors().add(out);
         bus.getOutFaultInterceptors().add(countingOut);
         bus.getOutFaultInterceptors().add(out);
-        //bus.setExtension(this, CounterRepository.class); 
-        
-        //create CounterRepositroyMoniter to writer the counter log
-        
-        //if the service is stopped or removed, the counters should remove itself
-    }
-    
-    static class TimerInfo {
-        Counter inFlight;
-        Timer totals;
-        Timer uncheckedApplicationFaults;
-        Timer checkedApplicationFaults;
-        Timer runtimeFaults;
-        Timer logicalRuntimeFaults;
-        Meter incomingData;
-        Meter outgoingData;
-     
-        Context start() {
-            inFlight.inc();
-            Context ctx = new Context();
-            ctx.info = this;
-            ctx.t = totals.time();
-            return ctx;
-        }
-        static class Context {
-            TimerInfo info;
-            Timer.Context t;
-        }
     }
-    
-    TimerInfo getTimerInfo(Message message) {
-        TimerInfo ti = (TimerInfo)message.getExchange().getEndpoint().get(TimerInfo.class.getName());
+        
+    MetricsContext getMetricsContextForEndpoint(Message message) {
+        MetricsContext ti = (MetricsContext)message.getExchange().getEndpoint().get(MetricsContext.class.getName());
         if (ti == null) {
             synchronized (message.getExchange().getEndpoint()) {
-                return createTimerInfo(message);
+                return createMetricsContextForEndpoint(message);
             }
         }
         return ti;
     }
-    TimerInfo getTimerInfo(Message message, BindingOperationInfo boi) {
+    MetricsContext getMetricsContextForOperation(Message message, BindingOperationInfo boi)
{
         if (boi.isUnwrapped()) {
             boi = boi.getWrappedOperation();
         }
-        TimerInfo ti = (TimerInfo)boi.getProperty(TimerInfo.class.getName());
+        MetricsContext ti = (MetricsContext)boi.getProperty(MetricsContext.class.getName());
         if (ti == null) {
             synchronized (boi) {
-                return createTimerInfo(message, boi);
+                return createMetricsContextForOperation(message, boi);
             }
         }
         return ti;
     }
-    private TimerInfo createTimerInfo(Message message, BindingOperationInfo boi) {
-        TimerInfo ti = (TimerInfo)boi.getProperty(TimerInfo.class.getName());
+    private MetricsContext createMetricsContextForOperation(Message message, BindingOperationInfo
boi) {
+        MetricsContext ti = (MetricsContext)boi.getProperty(MetricsContext.class.getName());
         if (ti == null) {
-            ti = new TimerInfo();
             StringBuilder buffer = getBaseServiceName(message);
             buffer.append("Operation=").append(boi.getName().getLocalPart()).append(',');
-            ti.totals = registry.timer(buffer.toString() + "Attribute=Totals");
-            ti.uncheckedApplicationFaults = registry.timer(buffer.toString() 
-                                                           + "Attribute=Unchecked Application
Faults");
-            ti.checkedApplicationFaults = registry.timer(buffer.toString() + "Attribute=Checked
Application Faults");
-            ti.runtimeFaults = registry.timer(buffer.toString() + "Attribute=Runtime Faults");
-            ti.logicalRuntimeFaults = registry.timer(buffer.toString() + "Attribute=Logical
Runtime Faults");
-            
-            boi.setProperty(TimerInfo.class.getName(), ti);
+            ti = new CodahaleMetricsContext(buffer.toString(), registry);
+            boi.setProperty(MetricsContext.class.getName(), ti);
         }
         return ti;
     }
@@ -203,47 +163,28 @@ public class Metrics {
         }
         return buffer;
     }
-    private TimerInfo createTimerInfo(Message message) {
+    private MetricsContext createMetricsContextForEndpoint(Message message) {
         Exchange ex = message.getExchange();
         final Endpoint endpoint = ex.get(Endpoint.class);
-        TimerInfo ti = (TimerInfo)endpoint.get(TimerInfo.class.getName());
+        MetricsContext ti = (MetricsContext)endpoint.get(MetricsContext.class.getName());
         if (ti == null) {
-            ti = new TimerInfo();
             StringBuilder buffer = getBaseServiceName(message);
             final String baseName = buffer.toString();
-            ti.totals = registry.timer(baseName + "Attribute=Totals");
-            ti.uncheckedApplicationFaults = registry.timer(baseName 
-                                                           + "Attribute=Unchecked Application
Faults");
-            ti.checkedApplicationFaults = registry.timer(baseName + "Attribute=Checked Application
Faults");
-            ti.runtimeFaults = registry.timer(baseName + "Attribute=Runtime Faults");
-            ti.logicalRuntimeFaults = registry.timer(baseName + "Attribute=Logical Runtime
Faults");
-            ti.inFlight = registry.counter(baseName + "Attribute=In Flight");
-            ti.incomingData = registry.meter(baseName + "Attribute=Data Read");
-            ti.outgoingData = registry.meter(baseName + "Attribute=Data Written");
-            endpoint.put(TimerInfo.class.getName(), ti);
+            ti = new CodahaleMetricsContext(baseName, registry);
+            
+
+            endpoint.put(MetricsContext.class.getName(), ti);
             endpoint.addCleanupHook(new Closeable() {
                 public void close() throws IOException {
                     try {
-                        registry.remove(baseName + "Attribute=Totals");
-                        registry.remove(baseName + "Attribute=Unchecked Application Faults");
-                        registry.remove(baseName + "Attribute=Checked Application Faults");
-                        registry.remove(baseName + "Attribute=Runtime Faults");
-                        registry.remove(baseName + "Attribute=Logical Runtime Faults");
-                        registry.remove(baseName + "Attribute=In Flight");
-                        registry.remove(baseName + "Attribute=Data Read");
-                        registry.remove(baseName + "Attribute=Data Written");
-                        endpoint.remove(TimerInfo.class.getName());
-                        System.out.println(endpoint.getBinding().getBindingInfo().getOperations());
+                        MetricsContext mct = (MetricsContext)endpoint.remove(MetricsContext.class.getName());
+                        if (mct instanceof Closeable) {
+                            ((Closeable)mct).close();
+                        }
                         for (BindingOperationInfo boi : endpoint.getBinding().getBindingInfo().getOperations())
{
-                            TimerInfo ti = (TimerInfo)boi.removeProperty(TimerInfo.class.getName());
-                            if (ti != null) {
-                                String name = baseName + "Operation=" + boi.getName().getLocalPart()
+ ",";
-                                System.out.println("Removing beans for " + boi.getName().getLocalPart());
-                                registry.remove(name + "Attribute=Totals");
-                                registry.remove(name + "Attribute=Unchecked Application Faults");
-                                registry.remove(name + "Attribute=Checked Application Faults");
-                                registry.remove(name + "Attribute=Runtime Faults");
-                                registry.remove(name + "Attribute=Logical Runtime Faults");
                           
+                            MetricsContext ti = (MetricsContext)boi.removeProperty(MetricsContext.class.getName());
+                            if (ti instanceof Closeable) {
+                                ((Closeable)ti).close();
                             }
                         }
                     } catch (Throwable t) {
@@ -262,50 +203,10 @@ public class Metrics {
         return value;
     }
 
-    static void update(Timer t1, Timer t2, long t) {
-        if (t1 != null) {
-            t1.update(t,  TimeUnit.NANOSECONDS);
-        }
-        if (t2 != null) {
-            t2.update(t,  TimeUnit.NANOSECONDS);
-        }
-    }
     public void stopTimers(Message m) {
-        TimerInfo.Context ctx = m.getExchange().get(TimerInfo.Context.class);
-        long l = ctx.t.stop();
-        ctx.info.inFlight.dec();
-        BindingOperationInfo bi = m.getExchange().getBindingOperationInfo();
-        FaultMode fm = m.getExchange().get(FaultMode.class);
-        TimerInfo op = null;
-        CountingInputStream in = m.getExchange().get(CountingInputStream.class);
-        if (in != null) {
-            ctx.info.incomingData.mark(in.getCount());
-        }
-        CountingOutputStream out = m.getExchange().get(CountingOutputStream.class);
-        if (out != null) {
-            ctx.info.outgoingData.mark(out.getCount());
-        }
-
-        if (bi != null) {
-            op = getTimerInfo(m, bi);
-            op.totals.update(l, TimeUnit.NANOSECONDS);
-        }
-        if (fm != null) {
-            switch (fm) {
-            case CHECKED_APPLICATION_FAULT:
-                update(ctx.info.checkedApplicationFaults, op != null ? op.checkedApplicationFaults
: null, l);
-                break;
-            case UNCHECKED_APPLICATION_FAULT:
-                update(ctx.info.uncheckedApplicationFaults, op != null ? op.uncheckedApplicationFaults
: null, l);
-                break;
-            case RUNTIME_FAULT:
-                update(ctx.info.runtimeFaults, op != null ? op.runtimeFaults : null, l);
-                break;
-            case LOGICAL_RUNTIME_FAULT:
-                update(ctx.info.logicalRuntimeFaults, op != null ? op.logicalRuntimeFaults
: null, l);
-                break;
-            default:
-            }
+        MessageMetrics ctx = m.getExchange().get(MessageMetrics.class);
+        if (ctx != null) {
+            ctx.stop(m);
         }
     }
     
@@ -316,18 +217,23 @@ public class Metrics {
             addBefore(AttachmentInInterceptor.class.getName());
         }
         public void handleMessage(Message message) throws Fault {
-            TimerInfo ti = getTimerInfo(message);
             if (isRequestor(message)) {
                 //
             } else {
-                TimerInfo.Context ctx = ti.start();
-                message.getExchange().put(TimerInfo.Context.class, ctx);
+                MessageMetrics ctx = message.getExchange().get(MessageMetrics.class);
+                if (ctx == null) {
+                    ctx = new MessageMetrics();
+                    MetricsContext ti = getMetricsContextForEndpoint(message);
+                    ctx.addContext(ti);
+                    message.getExchange().put(MessageMetrics.class, ctx);
+                }
                 InputStream in = message.getContent(InputStream.class);
                 if (in != null) {
                     CountingInputStream newIn = new CountingInputStream(in);
                     message.setContent(InputStream.class, newIn);
                     message.getExchange().put(CountingInputStream.class, newIn);
                 }
+                ctx.start();
             }
         }
         public void handleFault(Message message) {
@@ -370,6 +276,23 @@ public class Metrics {
             }
         }    
     };
+    class ResponseTimeMessageInPreInvokeInterceptor extends AbstractPhaseInterceptor<Message>
{
+        public ResponseTimeMessageInPreInvokeInterceptor() {
+            super(Phase.PRE_INVOKE);
+        }
+
+        public void handleMessage(Message message) throws Fault {
+            Exchange ex = message.getExchange();
+            if (ex.getBindingOperationInfo() != null) {
+                //we now know the operation, start metrics for it
+                MessageMetrics ctx = message.getExchange().get(MessageMetrics.class);
+                if (ctx != null) {
+                    MetricsContext ti = getMetricsContextForOperation(message, ex.getBindingOperationInfo());
+                    ctx.addContext(ti);
+                }
+            }
+        }               
+    }
     class ResponseTimeMessageInOneWayInterceptor extends AbstractPhaseInterceptor<Message>
{
         public ResponseTimeMessageInOneWayInterceptor() {
             super(Phase.INVOKE);

http://git-wip-us.apache.org/repos/asf/cxf/blob/c5da4140/rt/management/src/main/java/org/apache/cxf/management/codahale/MetricsContext.java
----------------------------------------------------------------------
diff --git a/rt/management/src/main/java/org/apache/cxf/management/codahale/MetricsContext.java
b/rt/management/src/main/java/org/apache/cxf/management/codahale/MetricsContext.java
new file mode 100644
index 0000000..f77bc0a
--- /dev/null
+++ b/rt/management/src/main/java/org/apache/cxf/management/codahale/MetricsContext.java
@@ -0,0 +1,47 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.cxf.management.codahale;
+
+
+import org.apache.cxf.message.FaultMode;
+
+
+/**
+ * Class to hold all the various metric pieces for a given context (Endpoint, Customer, Operation,
etc...)
+ */
+public interface MetricsContext {
+    
+    /**
+     * Will be called at the start of invoke (or when added to a started MessageMetrics).
 This is
+     * when the metrics should increment "inFlight" counts and other stats.   There is no
need to 
+     * record a "start time" as the invoke time will be passed into the stop method.
+     */
+    void start();
+    
+    /**
+     * Called when the invocation is complete.
+     * 
+     * @param timeInNS
+     * @param inSize
+     * @param outSize
+     * @param fm
+     */
+    void stop(long timeInNS, long inSize, long outSize, FaultMode fm);
+}


Mime
View raw message