Allow DOMNotificationRouter to be tuneable 43/20843/2
authorRobert Varga <rovarga@cisco.com>
Wed, 20 May 2015 15:53:21 +0000 (17:53 +0200)
committerGerrit Code Review <gerrit@opendaylight.org>
Sun, 24 May 2015 13:56:49 +0000 (13:56 +0000)
The details of how deep is the queue and how the backoff strategy is
applied should be tuneable. Model them and provide the hooks.

Change-Id: I6eda6bebc2cf506d627e09d3949a73e97ed866e4
Signed-off-by: Robert Varga <rovarga@cisco.com>
(cherry picked from commit 1ef2ed07ea9d7d42963b8b2ce5e99004f6c33274)

opendaylight/md-sal/md-sal-config/src/main/resources/initial/01-md-sal.xml
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/config/yang/md/sal/dom/impl/DomBrokerImplModule.java
opendaylight/md-sal/sal-dom-broker/src/main/java/org/opendaylight/controller/md/sal/dom/broker/impl/DOMNotificationRouter.java
opendaylight/md-sal/sal-dom-broker/src/main/yang/opendaylight-dom-broker-impl.yang

index 0176523b8646592149e97d62731bc3796afe8999..3d66a79d7b2c0b689338f72ea032a8bc82ff8b1a 100644 (file)
                         <type xmlns:dom="urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom">dom:dom-async-data-broker</type>
                         <name>inmemory-data-broker</name>
                     </async-data-broker>
+                    <notification-queue-depth>65536</notification-queue-depth>
+                    <notification-queue-spin>1</notification-queue-spin>
+                    <notification-queue-park>30</notification-queue-park>
                 </module>
                 <module>
                     <type xmlns:prefix="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding:impl">prefix:binding-data-compatible-broker</type>
index 35c22a1bee122d31b67bcd700c571b5f283ffc95..fbae80b1f9fa4b3547101cc9005bf9c781e7c6bb 100644 (file)
@@ -7,8 +7,10 @@
  */
 package org.opendaylight.controller.config.yang.md.sal.dom.impl;
 
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ClassToInstanceMap;
 import com.google.common.collect.MutableClassToInstanceMap;
+import java.util.concurrent.TimeUnit;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
 import org.opendaylight.controller.md.sal.dom.api.DOMMountPointService;
 import org.opendaylight.controller.md.sal.dom.api.DOMNotificationPublishService;
@@ -23,9 +25,6 @@ import org.opendaylight.controller.sal.core.api.model.SchemaService;
 import org.opendaylight.controller.sal.dom.broker.BrokerImpl;
 import org.opendaylight.controller.sal.dom.broker.GlobalBundleScanningSchemaServiceImpl;
 
-/**
-*
-*/
 public final class DomBrokerImplModule extends org.opendaylight.controller.config.yang.md.sal.dom.impl.AbstractDomBrokerImplModule
 {
 
@@ -38,8 +37,10 @@ public final class DomBrokerImplModule extends org.opendaylight.controller.confi
     }
 
     @Override
-    public void validate(){
+    public void validate() {
         super.validate();
+        final long depth = getNotificationQueueDepth().getValue();
+        Preconditions.checkArgument(Long.lowestOneBit(depth) == Long.highestOneBit(depth), "Queue depth %s is not power-of-two", depth);
     }
 
     @Override
@@ -48,10 +49,8 @@ public final class DomBrokerImplModule extends org.opendaylight.controller.confi
 
         final ClassToInstanceMap<BrokerService> services = MutableClassToInstanceMap.create();
 
-        // TODO: retrieve from config subsystem
-        final int queueDepth = 1024;
-
-        final DOMNotificationRouter domNotificationRouter = DOMNotificationRouter.create(queueDepth);
+        final DOMNotificationRouter domNotificationRouter = DOMNotificationRouter.create(getNotificationQueueDepth().getValue().intValue(),
+            getNotificationQueueSpin().longValue(), getNotificationQueuePark().longValue(), TimeUnit.MILLISECONDS);
         services.putInstance(DOMNotificationService.class, domNotificationRouter);
         services.putInstance(DOMNotificationPublishService.class, domNotificationRouter);
 
index d623c3ec969fed939fde3b683639837161a9e72b..138de6b77068fc06ee9cd4e1dbe160a94f3a92fc 100644 (file)
@@ -81,21 +81,27 @@ public final class DOMNotificationRouter implements AutoCloseable, DOMNotificati
     private volatile Multimap<SchemaPath, ListenerRegistration<? extends DOMNotificationListener>> listeners = ImmutableMultimap.of();
     private final ListenerRegistry<DOMNotificationSubscriptionListener> subscriptionListeners = ListenerRegistry.create();
 
-    private DOMNotificationRouter(final ExecutorService executor, final Disruptor<DOMNotificationRouterEvent> disruptor) {
+    @SuppressWarnings("unchecked")
+    private DOMNotificationRouter(final ExecutorService executor, final int queueDepth, final WaitStrategy strategy) {
         this.executor = Preconditions.checkNotNull(executor);
-        this.disruptor = Preconditions.checkNotNull(disruptor);
+
+        disruptor = new Disruptor<>(DOMNotificationRouterEvent.FACTORY, queueDepth, executor, ProducerType.MULTI, strategy);
+        disruptor.handleEventsWith(DISPATCH_NOTIFICATIONS);
+        disruptor.after(DISPATCH_NOTIFICATIONS).handleEventsWith(NOTIFY_FUTURE);
+        disruptor.start();
     }
 
-    @SuppressWarnings("unchecked")
     public static DOMNotificationRouter create(final int queueDepth) {
         final ExecutorService executor = Executors.newCachedThreadPool();
-        final Disruptor<DOMNotificationRouterEvent> disruptor = new Disruptor<>(DOMNotificationRouterEvent.FACTORY, queueDepth, executor, ProducerType.MULTI, DEFAULT_STRATEGY);
 
-        disruptor.handleEventsWith(DISPATCH_NOTIFICATIONS);
-        disruptor.after(DISPATCH_NOTIFICATIONS).handleEventsWith(NOTIFY_FUTURE);
-        disruptor.start();
+        return new DOMNotificationRouter(executor, queueDepth, DEFAULT_STRATEGY);
+    }
+
+    public static DOMNotificationRouter create(final int queueDepth, final long spinTime, final long parkTime, final TimeUnit unit) {
+        final ExecutorService executor = Executors.newCachedThreadPool();
+        final WaitStrategy strategy = PhasedBackoffWaitStrategy.withLock(spinTime, parkTime, unit);
 
-        return new DOMNotificationRouter(executor, disruptor);
+        return new DOMNotificationRouter(executor, queueDepth, strategy);
     }
 
     @Override
index f06ff627222aed882f87f1ce7012d5db86f71371..7655a921ec7973e4a6a06ba870cbd06d02e30a56 100644 (file)
@@ -40,6 +40,12 @@ module opendaylight-sal-dom-broker-impl {
         config:java-name-prefix SchemaServiceImplSingleton;
     }
 
+    typedef max-queue-depth {
+        type uint32 {
+            range 1..1073741824;
+        }
+    }
+
     augment "/config:modules/config:module/config:configuration" {
         case dom-broker-impl {
             when "/config:modules/config:module/config:type = 'dom-broker-impl'";
@@ -61,6 +67,24 @@ module opendaylight-sal-dom-broker-impl {
                     }
                 }
             }
+
+            leaf notification-queue-depth {
+                description "Maximum number of elements in the notification queue, must be power-of-two.";
+                type max-queue-depth;
+                default 65536;
+            }
+            leaf notification-queue-spin {
+                description "Number of milliseconds notification queue should spin for new requests before parking.";
+                type uint16;
+                units milliseconds;
+                default 1;
+            }
+            leaf notification-queue-park {
+                description "Number of milliseconds notification queue should park for new requests before blocking.";
+                type uint16;
+                units milliseconds;
+                default 30;
+            }
         }
     }