Improve notification delivery defensiveness
[mdsal.git] / dom / mdsal-dom-broker / src / main / java / org / opendaylight / mdsal / dom / broker / DOMNotificationRouterEvent.java
index 6eafd0696fc126235f48c9960f133db865992452..9dd4f6a3ec999aab0a58261c6e3ae21a31a31a8b 100644 (file)
@@ -15,16 +15,19 @@ import com.lmax.disruptor.EventFactory;
 import java.util.Collection;
 import org.opendaylight.mdsal.dom.api.DOMNotification;
 import org.opendaylight.mdsal.dom.api.DOMNotificationListener;
-import org.opendaylight.yangtools.concepts.ListenerRegistration;
+import org.opendaylight.yangtools.concepts.AbstractListenerRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
- * A single notification event in the disruptor ringbuffer. These objects are reused,
- * so they do have mutable state.
+ * A single notification event in the disruptor ringbuffer. These objects are reused, so they do have mutable state.
  */
 final class DOMNotificationRouterEvent {
+    private static final Logger LOG = LoggerFactory.getLogger(DOMNotificationRouterEvent.class);
+
     static final EventFactory<DOMNotificationRouterEvent> FACTORY = DOMNotificationRouterEvent::new;
 
-    private Collection<ListenerRegistration<? extends DOMNotificationListener>> subscribers;
+    private Collection<AbstractListenerRegistration<? extends DOMNotificationListener>> subscribers;
     private DOMNotification notification;
     private SettableFuture<Void> future;
 
@@ -34,18 +37,23 @@ final class DOMNotificationRouterEvent {
 
     @SuppressWarnings("checkstyle:hiddenField")
     ListenableFuture<Void> initialize(final DOMNotification notification,
-            final Collection<ListenerRegistration<? extends DOMNotificationListener>> subscribers) {
+            final Collection<AbstractListenerRegistration<? extends DOMNotificationListener>> subscribers) {
         this.notification = requireNonNull(notification);
         this.subscribers = requireNonNull(subscribers);
         this.future = SettableFuture.create();
         return this.future;
     }
 
+    @SuppressWarnings("checkstyle:illegalCatch")
     void deliverNotification() {
-        for (ListenerRegistration<? extends DOMNotificationListener> r : subscribers) {
-            final DOMNotificationListener l = r.getInstance();
-            if (l != null) {
-                l.onNotification(notification);
+        for (AbstractListenerRegistration<? extends DOMNotificationListener> reg : subscribers) {
+            if (reg.notClosed()) {
+                final DOMNotificationListener listener = reg.getInstance();
+                try {
+                    listener.onNotification(notification);
+                } catch (Exception e) {
+                    LOG.warn("Listener {} failed during notification delivery", listener, e);
+                }
             }
         }
     }
@@ -53,5 +61,4 @@ final class DOMNotificationRouterEvent {
     void setFuture() {
         future.set(null);
     }
-
-}
\ No newline at end of file
+}