From 7e0482f5a2f6abed7a3af2f4313f557692a15d1d Mon Sep 17 00:00:00 2001 From: Robert Varga Date: Tue, 18 Feb 2014 07:43:15 +0100 Subject: [PATCH 1/1] Place an upper bound on notification concurrency 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 --- .../binding/codegen/impl/SingletonHolder.java | 38 ++++++++++++------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/SingletonHolder.java b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/SingletonHolder.java index a0bbb28d9e..790c1fcd4c 100644 --- a/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/SingletonHolder.java +++ b/opendaylight/md-sal/sal-binding-broker/src/main/java/org/opendaylight/controller/sal/binding/codegen/impl/SingletonHolder.java @@ -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(), 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(); -- 2.36.6