killbill-uncached

Refactoring profiling

7/30/2014 4:33:28 PM

Details

jaxrs/pom.xml 8(+4 -4)

diff --git a/jaxrs/pom.xml b/jaxrs/pom.xml
index 716d1ed..40d85cf 100644
--- a/jaxrs/pom.xml
+++ b/jaxrs/pom.xml
@@ -87,10 +87,6 @@
         </dependency>
         <dependency>
             <groupId>org.kill-bill.billing</groupId>
-            <artifactId>killbill-platform-base</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.kill-bill.billing</groupId>
             <artifactId>killbill-platform-test</artifactId>
             <scope>test</scope>
         </dependency>
@@ -123,6 +119,10 @@
         </dependency>
         <dependency>
             <groupId>org.kill-bill.commons</groupId>
+            <artifactId>killbill-concurrent</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.kill-bill.commons</groupId>
             <artifactId>killbill-embeddeddb-h2</artifactId>
             <scope>test</scope>
         </dependency>
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/ProfilingDataJson.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/ProfilingDataJson.java
index 96d6096..f3a9ce4 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/ProfilingDataJson.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/json/ProfilingDataJson.java
@@ -17,36 +17,116 @@
 
 package org.killbill.billing.jaxrs.json;
 
-import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
-import java.util.Map;
+import java.util.Stack;
 
-import org.killbill.billing.platform.profiling.ProfilingData;
+import org.killbill.commons.profiling.ProfilingData;
+import org.killbill.commons.profiling.ProfilingData.LogLineType;
+import org.killbill.commons.profiling.ProfilingData.ProfilingDataItem;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.fasterxml.jackson.annotation.JsonProperty;
+import com.google.common.base.Preconditions;
 
 public class ProfilingDataJson {
 
-    private final Map<String, List<Long>> rawData;
-    private final String createdUri;
+    private final List<ProfilingDataJsonItem> rawData;
 
     @JsonCreator
-    public ProfilingDataJson(@JsonProperty("createdUri") final String createdUri,
-            @JsonProperty("rawData") final Map<String, List<Long>> rawData) {
-        this.createdUri = createdUri;
+    public ProfilingDataJson(@JsonProperty("rawData") final List<ProfilingDataJsonItem> rawData) {
         this.rawData = rawData;
     }
 
-    public ProfilingDataJson(final ProfilingData data, final URI uri) {
-        this(uri.getPath(), data.getRawData());
+    public ProfilingDataJson(final ProfilingData input) {
+        final List<ProfilingDataItem> items = input.getRawData();
+        if (items.isEmpty()) {
+            this.rawData = Collections.emptyList();
+            return;
+        }
+
+        final List<ProfilingDataJsonItem> root = new ArrayList<ProfilingDataJsonItem>();
+
+        final Stack<ProfilingDataJsonItem> stack = new Stack<ProfilingDataJsonItem>();
+        while (items.size() > 0) {
+
+            final ProfilingDataItem cur = items.remove(0);
+
+            if (cur.getLineType() == LogLineType.START) {
+
+                // Create new element
+                final ProfilingDataJsonItem jsonItem = new ProfilingDataJsonItem(cur.getKey(), nanoToMicro(cur.getTimestampNsec()), Long.MIN_VALUE, new ArrayList<ProfilingDataJsonItem>());
+                // If stack is empty this belong to top level list, if to the parent's list
+                if (stack.isEmpty()) {
+                    root.add(jsonItem);
+                } else {
+                    final ProfilingDataJsonItem parent = stack.peek();
+                    parent.addChild(jsonItem);
+                }
+                // Add current element to the stack
+                stack.push(jsonItem);
+            } else /* LogLineType.STOP */ {
+                // Fetch current element and update its duration time
+                final ProfilingDataJsonItem jsonItem = stack.pop();
+                jsonItem.setDurationUsec(nanoToMicro(cur.getTimestampNsec()) - jsonItem.getStartUsec());
+            }
+        }
+        Preconditions.checkState(stack.isEmpty());
+        this.rawData = root;
     }
 
-    public Map<String, List<Long>> getRawData() {
+    public List<ProfilingDataJsonItem> getRawData() {
         return rawData;
     }
 
-    public String getCreatedUri() {
-        return createdUri;
+    public class ProfilingDataJsonItem {
+
+        private final String name;
+        private final Long startUsec;
+        private final List<ProfilingDataJsonItem> calls;
+        // Not final so we can build the data structure in one pass
+        private Long durationUsec;
+
+        @JsonCreator
+        public ProfilingDataJsonItem(@JsonProperty("name") final String name,
+                                     @JsonProperty("startUsec") final Long startUsec,
+                                     @JsonProperty("durationUsec") final Long durationUsec,
+                                     @JsonProperty("calls") final List<ProfilingDataJsonItem> calls) {
+            this.name = name;
+            this.startUsec = startUsec;
+            this.durationUsec = durationUsec;
+            this.calls = calls;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        @JsonIgnore
+        public Long getStartUsec() {
+            return startUsec;
+        }
+
+        public Long getDurationUsec() {
+            return durationUsec;
+        }
+
+        public void addChild(final ProfilingDataJsonItem child) {
+            calls.add(child);
+        }
+
+        public List<ProfilingDataJsonItem> getCalls() {
+            return calls;
+        }
+
+        public void setDurationUsec(final Long durationUsec) {
+            this.durationUsec = durationUsec;
+        }
+    }
+
+    private static Long nanoToMicro(final Long nanoSec) {
+        return (nanoSec / 1000);
     }
 }
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxRsResourceBase.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxRsResourceBase.java
index 9c656a5..e3d8de4 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxRsResourceBase.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/resources/JaxRsResourceBase.java
@@ -61,8 +61,6 @@ import org.killbill.billing.payment.api.PaymentOptions;
 import org.killbill.billing.payment.api.PaymentTransaction;
 import org.killbill.billing.payment.api.PluginProperty;
 import org.killbill.billing.payment.api.TransactionType;
-import org.killbill.billing.platform.profiling.Profiling;
-import org.killbill.billing.platform.profiling.ProfilingData.ProfilingDataOutput;
 import org.killbill.billing.util.api.AuditUserApi;
 import org.killbill.billing.util.api.CustomFieldApiException;
 import org.killbill.billing.util.api.CustomFieldUserApi;
diff --git a/jaxrs/src/main/java/org/killbill/billing/jaxrs/util/JaxrsUriBuilder.java b/jaxrs/src/main/java/org/killbill/billing/jaxrs/util/JaxrsUriBuilder.java
index 7cc3044..c63c399 100644
--- a/jaxrs/src/main/java/org/killbill/billing/jaxrs/util/JaxrsUriBuilder.java
+++ b/jaxrs/src/main/java/org/killbill/billing/jaxrs/util/JaxrsUriBuilder.java
@@ -26,8 +26,8 @@ import javax.ws.rs.core.UriInfo;
 import org.killbill.billing.jaxrs.json.ProfilingDataJson;
 import org.killbill.billing.jaxrs.resources.JaxRsResourceBase;
 import org.killbill.billing.jaxrs.resources.JaxrsResource;
-import org.killbill.billing.platform.profiling.Profiling;
-import org.killbill.billing.platform.profiling.ProfilingData;
+import org.killbill.commons.profiling.Profiling;
+import org.killbill.commons.profiling.ProfilingData;
 
 public class JaxrsUriBuilder {
 
@@ -73,7 +73,7 @@ public class JaxrsUriBuilder {
             public URI getUri() {
                 return newUriFromResource;
             }
-        } : new ProfilingDataJson(profilingData, newUriFromResource);
+        } : new ProfilingDataJson(profilingData);
 
         return ri.entity(obj).build();
     }

payment/pom.xml 4(+0 -4)

diff --git a/payment/pom.xml b/payment/pom.xml
index 00e0c82..766e925 100644
--- a/payment/pom.xml
+++ b/payment/pom.xml
@@ -100,10 +100,6 @@
         </dependency>
         <dependency>
             <groupId>org.kill-bill.billing</groupId>
-            <artifactId>killbill-platform-base</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.kill-bill.billing</groupId>
             <artifactId>killbill-platform-lifecycle</artifactId>
         </dependency>
         <dependency>
diff --git a/payment/src/main/java/org/killbill/billing/payment/dispatcher/PluginDispatcher.java b/payment/src/main/java/org/killbill/billing/payment/dispatcher/PluginDispatcher.java
index dd1ba05..a60eff6 100644
--- a/payment/src/main/java/org/killbill/billing/payment/dispatcher/PluginDispatcher.java
+++ b/payment/src/main/java/org/killbill/billing/payment/dispatcher/PluginDispatcher.java
@@ -25,10 +25,8 @@ import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
-import org.killbill.billing.platform.profiling.Profiling;
-import org.killbill.billing.platform.profiling.ProfilingData;
-
-import com.google.common.base.Preconditions;
+import org.killbill.commons.profiling.Profiling;
+import org.killbill.commons.profiling.ProfilingData;
 
 public class PluginDispatcher<ReturnType> {
 
diff --git a/payment/src/main/java/org/killbill/billing/payment/glue/PaymentModule.java b/payment/src/main/java/org/killbill/billing/payment/glue/PaymentModule.java
index c7cf91f..f5a8722 100644
--- a/payment/src/main/java/org/killbill/billing/payment/glue/PaymentModule.java
+++ b/payment/src/main/java/org/killbill/billing/payment/glue/PaymentModule.java
@@ -19,11 +19,9 @@
 package org.killbill.billing.payment.glue;
 
 import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
 
 import javax.inject.Provider;
@@ -39,10 +37,10 @@ import org.killbill.billing.payment.api.PaymentService;
 import org.killbill.billing.payment.bus.InvoiceHandler;
 import org.killbill.billing.payment.control.PaymentTagHandler;
 import org.killbill.billing.payment.control.dao.InvoicePaymentControlDao;
-import org.killbill.billing.payment.core.PaymentProcessor;
 import org.killbill.billing.payment.core.Janitor;
 import org.killbill.billing.payment.core.PaymentGatewayProcessor;
 import org.killbill.billing.payment.core.PaymentMethodProcessor;
+import org.killbill.billing.payment.core.PaymentProcessor;
 import org.killbill.billing.payment.core.PluginControlledPaymentProcessor;
 import org.killbill.billing.payment.core.sm.PaymentStateMachineHelper;
 import org.killbill.billing.payment.core.sm.PluginControlledPaymentAutomatonRunner;
@@ -55,10 +53,10 @@ import org.killbill.billing.payment.retry.DefaultRetryService;
 import org.killbill.billing.payment.retry.DefaultRetryService.DefaultRetryServiceScheduler;
 import org.killbill.billing.payment.retry.RetryService;
 import org.killbill.billing.platform.api.KillbillConfigSource;
-import org.killbill.billing.platform.profiling.WithProfilingThreadPoolExecutor;
 import org.killbill.billing.retry.plugin.api.PaymentControlPluginApi;
 import org.killbill.billing.util.config.PaymentConfig;
 import org.killbill.billing.util.glue.KillBillModule;
+import org.killbill.commons.concurrent.WithProfilingThreadPoolExecutor;
 import org.killbill.xmlloader.XMLLoader;
 import org.skife.config.ConfigurationObjectFactory;
 
@@ -141,33 +139,18 @@ public class PaymentModule extends KillBillModule {
 
     protected void installProcessors(final PaymentConfig paymentConfig) {
 
-
         final ExecutorService pluginExecutorService = new WithProfilingThreadPoolExecutor(paymentConfig.getPaymentPluginThreadNb(), paymentConfig.getPaymentPluginThreadNb(),
-                                      0L, TimeUnit.MILLISECONDS,
-                                      new LinkedBlockingQueue<Runnable>(),
-                                      new ThreadFactory() {
-
-                                          @Override
-                                          public Thread newThread(final Runnable r) {
-                                              final Thread th = new Thread(r);
-                                              th.setName(PLUGIN_THREAD_PREFIX + th.getId());
-                                              return th;
-                                          }
-                                      });
-
-        /*
-        final ExecutorService pluginExecutorService = Executors.newFixedThreadPool(paymentConfig.getPaymentPluginThreadNb(), new ThreadFactory() {
-
-            @Override
-            public Thread newThread(final Runnable r) {
-                final Thread th = new Thread(r);
-                th.setName(PLUGIN_THREAD_PREFIX + th.getId());
-                return th;
-            }
-        });
-        */
-
-
+                                                                                          0L, TimeUnit.MILLISECONDS,
+                                                                                          new LinkedBlockingQueue<Runnable>(),
+                                                                                          new ThreadFactory() {
+
+                                                                                              @Override
+                                                                                              public Thread newThread(final Runnable r) {
+                                                                                                  final Thread th = new Thread(r);
+                                                                                                  th.setName(PLUGIN_THREAD_PREFIX + th.getId());
+                                                                                                  return th;
+                                                                                              }
+                                                                                          });
         bind(ExecutorService.class).annotatedWith(Names.named(PLUGIN_EXECUTOR_NAMED)).toInstance(pluginExecutorService);
         bind(PaymentProcessor.class).asEagerSingleton();
         bind(PluginControlledPaymentProcessor.class).asEagerSingleton();
diff --git a/payment/src/test/java/org/killbill/billing/payment/core/sm/TestPluginOperation.java b/payment/src/test/java/org/killbill/billing/payment/core/sm/TestPluginOperation.java
index 0c9bb88..fbf4a8c 100644
--- a/payment/src/test/java/org/killbill/billing/payment/core/sm/TestPluginOperation.java
+++ b/payment/src/test/java/org/killbill/billing/payment/core/sm/TestPluginOperation.java
@@ -41,8 +41,6 @@ import org.killbill.billing.payment.dispatcher.PluginDispatcher;
 import org.killbill.billing.payment.dispatcher.PluginDispatcher.PluginDispatcherReturnType;
 import org.killbill.billing.payment.plugin.api.PaymentPluginApiException;
 import org.killbill.billing.payment.plugin.api.PaymentTransactionInfoPlugin;
-import org.killbill.billing.platform.profiling.Profiling;
-import org.killbill.billing.platform.profiling.ProfilingData.ProfilingDataOutput;
 import org.killbill.commons.locker.GlobalLocker;
 import org.killbill.commons.locker.memory.MemoryGlobalLocker;
 import org.mockito.Mockito;
diff --git a/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteNoDB.java b/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteNoDB.java
index 4df4fbd..f3a3b48 100644
--- a/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteNoDB.java
+++ b/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteNoDB.java
@@ -34,9 +34,9 @@ import org.killbill.billing.payment.plugin.api.PaymentPluginApi;
 import org.killbill.billing.payment.provider.MockPaymentProviderPlugin;
 import org.killbill.billing.payment.retry.DefaultRetryService;
 import org.killbill.billing.platform.api.KillbillConfigSource;
-import org.killbill.billing.platform.profiling.Profiling;
 import org.killbill.billing.util.config.PaymentConfig;
 import org.killbill.bus.api.PersistentBus;
+import org.killbill.commons.profiling.Profiling;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
diff --git a/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteWithEmbeddedDB.java b/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteWithEmbeddedDB.java
index 05b20bd..3d144dc 100644
--- a/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteWithEmbeddedDB.java
+++ b/payment/src/test/java/org/killbill/billing/payment/PaymentTestSuiteWithEmbeddedDB.java
@@ -31,9 +31,9 @@ import org.killbill.billing.payment.glue.TestPaymentModuleWithEmbeddedDB;
 import org.killbill.billing.payment.plugin.api.PaymentPluginApi;
 import org.killbill.billing.payment.provider.MockPaymentProviderPlugin;
 import org.killbill.billing.platform.api.KillbillConfigSource;
-import org.killbill.billing.platform.profiling.Profiling;
 import org.killbill.billing.util.config.PaymentConfig;
 import org.killbill.bus.api.PersistentBus;
+import org.killbill.commons.profiling.Profiling;
 import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
diff --git a/profiles/killbill/src/main/java/org/killbill/billing/server/listeners/KillbillGuiceListener.java b/profiles/killbill/src/main/java/org/killbill/billing/server/listeners/KillbillGuiceListener.java
index 1211004..af7cd3a 100644
--- a/profiles/killbill/src/main/java/org/killbill/billing/server/listeners/KillbillGuiceListener.java
+++ b/profiles/killbill/src/main/java/org/killbill/billing/server/listeners/KillbillGuiceListener.java
@@ -49,12 +49,13 @@ public class KillbillGuiceListener extends KillbillPlatformGuiceListener {
         final BaseServerModuleBuilder builder = new BaseServerModuleBuilder().setJaxrsUriPattern("(" + JaxRsResourceBase.PREFIX + "|" + JaxRsResourceBase.PLUGINS_PATH + ")" + "/.*")
                                                                              .addJaxrsResource("org.killbill.billing.jaxrs.mappers")
                                                                              .addJaxrsResource("org.killbill.billing.jaxrs.resources");
+        // Add profiling filter first
+        builder.addFilter("/*", ProfilingFilter.class);
 
+        // Add TenantFilter right after is multi-tenancy has been configured.
         if (config.isMultiTenancyEnabled()) {
             builder.addFilter("/*", TenantFilter.class);
         }
-
-        builder.addFilter("/*", ProfilingFilter.class);
         return builder.build();
     }
 
diff --git a/profiles/killbill/src/main/java/org/killbill/billing/server/profiling/ProfilingFilter.java b/profiles/killbill/src/main/java/org/killbill/billing/server/profiling/ProfilingFilter.java
index e6bc5df..1336d1c 100644
--- a/profiles/killbill/src/main/java/org/killbill/billing/server/profiling/ProfilingFilter.java
+++ b/profiles/killbill/src/main/java/org/killbill/billing/server/profiling/ProfilingFilter.java
@@ -28,8 +28,8 @@ import javax.servlet.ServletRequest;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 
-import org.killbill.billing.platform.profiling.Profiling;
-import org.killbill.billing.platform.profiling.ProfilingData.ProfilingDataOutput;
+import org.killbill.commons.profiling.Profiling;
+import org.killbill.commons.profiling.ProfilingData.ProfilingDataOutput;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 

util/pom.xml 8(+4 -4)

diff --git a/util/pom.xml b/util/pom.xml
index a69c56d..723fdd6 100644
--- a/util/pom.xml
+++ b/util/pom.xml
@@ -134,10 +134,6 @@
         </dependency>
         <dependency>
             <groupId>org.kill-bill.billing</groupId>
-            <artifactId>killbill-platform-base</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.kill-bill.billing</groupId>
             <artifactId>killbill-platform-osgi-api</artifactId>
             <scope>test</scope>
         </dependency>
@@ -170,6 +166,10 @@
         </dependency>
         <dependency>
             <groupId>org.kill-bill.commons</groupId>
+            <artifactId>killbill-concurrent</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.kill-bill.commons</groupId>
             <artifactId>killbill-embeddeddb-common</artifactId>
             <scope>compile</scope>
         </dependency>
diff --git a/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoWrapperInvocationHandler.java b/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoWrapperInvocationHandler.java
index 2651f2c..30bc491 100644
--- a/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoWrapperInvocationHandler.java
+++ b/util/src/main/java/org/killbill/billing/util/entity/dao/EntitySqlDaoWrapperInvocationHandler.java
@@ -30,9 +30,9 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.killbill.billing.platform.profiling.Profiling;
-import org.killbill.billing.platform.profiling.Profiling.WithProfilingCallback;
 import org.killbill.billing.util.tag.dao.UUIDCollectionBinder;
+import org.killbill.commons.profiling.Profiling;
+import org.killbill.commons.profiling.Profiling.WithProfilingCallback;
 import org.skife.jdbi.v2.Binding;
 import org.skife.jdbi.v2.StatementContext;
 import org.skife.jdbi.v2.exceptions.DBIException;
diff --git a/util/src/main/java/org/killbill/billing/util/glue/KillbillApiAopModule.java b/util/src/main/java/org/killbill/billing/util/glue/KillbillApiAopModule.java
index ce34cc8..63012fd 100644
--- a/util/src/main/java/org/killbill/billing/util/glue/KillbillApiAopModule.java
+++ b/util/src/main/java/org/killbill/billing/util/glue/KillbillApiAopModule.java
@@ -20,8 +20,8 @@ package org.killbill.billing.util.glue;
 import org.aopalliance.intercept.MethodInterceptor;
 import org.aopalliance.intercept.MethodInvocation;
 import org.killbill.billing.KillbillApi;
-import org.killbill.billing.platform.profiling.Profiling;
-import org.killbill.billing.platform.profiling.Profiling.WithProfilingCallback;
+import org.killbill.commons.profiling.Profiling;
+import org.killbill.commons.profiling.Profiling.WithProfilingCallback;
 
 import com.google.inject.AbstractModule;
 import com.google.inject.matcher.Matchers;