Place an upper bound on notification concurrency 81/5381/3
authorRobert Varga <rovarga@cisco.com>
Tue, 18 Feb 2014 06:43:15 +0000 (07:43 +0100)
committerRobert Varga <rovarga@cisco.com>
Tue, 18 Feb 2014 08:42:52 +0000 (09:42 +0100)
In Cbench tests we have seen as many as 2000 threads being created. This
is certainly an overkill and thus let's place an upper bound on the
number of threads we create.

Change-Id: I6a7f429080504cbfa75679cc5879264a0622f140
Signed-off-by: Robert Varga <rovarga@cisco.com>
opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/SingletonHolder.java

index a0bbb28..790c1fc 100644 (file)
@@ -9,7 +9,10 @@ package org.opendaylight.controller.sal.binding.codegen.impl;
 
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
 
 import javassist.ClassPool;
 
@@ -27,13 +30,26 @@ public class SingletonHolder {
             CLASS_POOL);
     public static final RuntimeCodeGenerator RPC_GENERATOR = RPC_GENERATOR_IMPL;
     public static final NotificationInvokerFactory INVOKER_FACTORY = RPC_GENERATOR_IMPL.getInvokerFactory();
+
+    public static final int CORE_NOTIFICATION_THREADS = 4;
+    public static final int MAX_NOTIFICATION_THREADS = 32;
+    public static final int NOTIFICATION_THREAD_LIFE = 15;
+
     private static ListeningExecutorService NOTIFICATION_EXECUTOR = null;
     private static ListeningExecutorService COMMIT_EXECUTOR = null;
     private static ListeningExecutorService CHANGE_EVENT_EXECUTOR = null;
 
+    /**
+     * @deprecated This method is only used from configuration modules and thus callers of it
+     *             should use service injection to make the executor configurable.
+     */
+    @Deprecated
     public static synchronized final ListeningExecutorService getDefaultNotificationExecutor() {
         if (NOTIFICATION_EXECUTOR == null) {
-            NOTIFICATION_EXECUTOR = createNamedExecutor("md-sal-binding-notification-%d");
+            ThreadFactory factory = new ThreadFactoryBuilder().setDaemon(true).setNameFormat("md-sal-binding-notification-%d").build();
+            ExecutorService executor = new ThreadPoolExecutor(CORE_NOTIFICATION_THREADS, MAX_NOTIFICATION_THREADS,
+                    NOTIFICATION_THREAD_LIFE, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), factory);
+            NOTIFICATION_EXECUTOR = MoreExecutors.listeningDecorator(executor);
         }
         return NOTIFICATION_EXECUTOR;
     }
@@ -46,13 +62,13 @@ public class SingletonHolder {
     public static synchronized final ListeningExecutorService getDefaultCommitExecutor() {
         if (COMMIT_EXECUTOR == null) {
             ThreadFactory factory = new ThreadFactoryBuilder().setDaemon(true).setNameFormat("md-sal-binding-commit-%d").build();
-           /*
-            * FIXME: this used to be newCacheThreadPool(), but MD-SAL does not have transaction
-            *        ordering guarantees, which means that using a concurrent threadpool results
-            *        in application data being committed in random order, potentially resulting
-            *        in inconsistent data being present. Once proper primitives are introduced,
-            *        concurrency can be reintroduced.
-            */
+            /*
+             * FIXME: this used to be newCacheThreadPool(), but MD-SAL does not have transaction
+             *        ordering guarantees, which means that using a concurrent threadpool results
+             *        in application data being committed in random order, potentially resulting
+             *        in inconsistent data being present. Once proper primitives are introduced,
+             *        concurrency can be reintroduced.
+             */
             ExecutorService executor = Executors.newSingleThreadExecutor(factory);
             COMMIT_EXECUTOR = MoreExecutors.listeningDecorator(executor);
         }
@@ -60,12 +76,6 @@ public class SingletonHolder {
         return COMMIT_EXECUTOR;
     }
 
-    private static ListeningExecutorService createNamedExecutor(String format) {
-        ThreadFactory factory = new ThreadFactoryBuilder().setDaemon(true).setNameFormat(format).build();
-        ExecutorService executor = Executors.newCachedThreadPool(factory);
-        return MoreExecutors.listeningDecorator(executor);
-    }
-
     public static ExecutorService getDefaultChangeEventExecutor() {
         if (CHANGE_EVENT_EXECUTOR == null) {
             ThreadFactory factory = new ThreadFactoryBuilder().setDaemon(true).setNameFormat("md-sal-binding-change-%d").build();

©2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.
OpenDaylight is a registered trademark of The OpenDaylight Project, Inc.
Linux Foundation and OpenDaylight are registered trademarks of the Linux Foundation.
Linux is a registered trademark of Linus Torvalds.