Use terminate message in eos listener actors 11/97411/3
authorTomas Cere <tomas.cere@pantheon.tech>
Tue, 7 Sep 2021 09:49:19 +0000 (11:49 +0200)
committerRobert Varga <nite@hq.sk>
Wed, 8 Sep 2021 11:52:06 +0000 (11:52 +0000)
getContext().stop() can cause NPE during actor system
shutdown so lets use a terminate message here instead.
Its still possible to get dead letters with this approach
when the child actor was stopped first during the shutdown,
but at least we prevent the NPEs.

JIRA: CONTROLLER-1989
Change-Id: Id38b56c12141164d45ed19613885a4d9f650e4dd
Signed-off-by: Tomas Cere <tomas.cere@pantheon.tech>
opendaylight/md-sal/eos-dom-akka/src/main/java/org/opendaylight/controller/eos/akka/registry/listener/type/EntityTypeListenerActor.java
opendaylight/md-sal/eos-dom-akka/src/main/java/org/opendaylight/controller/eos/akka/registry/listener/type/EntityTypeListenerRegistry.java
opendaylight/md-sal/eos-dom-akka/src/main/java/org/opendaylight/controller/eos/akka/registry/listener/type/command/TerminateListener.java [new file with mode: 0644]

index 17391fa..e97fe77 100644 (file)
@@ -33,6 +33,7 @@ import org.opendaylight.controller.eos.akka.registry.listener.owner.SingleEntity
 import org.opendaylight.controller.eos.akka.registry.listener.owner.command.ListenerCommand;
 import org.opendaylight.controller.eos.akka.registry.listener.type.command.CandidatesChanged;
 import org.opendaylight.controller.eos.akka.registry.listener.type.command.EntityOwnerChanged;
+import org.opendaylight.controller.eos.akka.registry.listener.type.command.TerminateListener;
 import org.opendaylight.controller.eos.akka.registry.listener.type.command.TypeListenerCommand;
 import org.opendaylight.mdsal.eos.dom.api.DOMEntity;
 import org.opendaylight.mdsal.eos.dom.api.DOMEntityOwnershipListener;
@@ -69,6 +70,7 @@ public class EntityTypeListenerActor extends AbstractBehavior<TypeListenerComman
         return newReceiveBuilder()
                 .onMessage(CandidatesChanged.class, this::onCandidatesChanged)
                 .onMessage(EntityOwnerChanged.class, this::onOwnerChanged)
+                .onMessage(TerminateListener.class, this::onTerminate)
                 .build();
     }
 
@@ -113,6 +115,11 @@ public class EntityTypeListenerActor extends AbstractBehavior<TypeListenerComman
         return this;
     }
 
+    private Behavior<TypeListenerCommand> onTerminate(final TerminateListener command) {
+        LOG.debug("Terminating listener for type: {}, listener: {}", entityType, listener);
+        return Behaviors.stopped();
+    }
+
     private static String encodeEntityToActorName(final DOMEntity entity) {
         return "type=" + entity.getType() + ",entity="
                 + entity.getIdentifier().getLastPathArgument().getNodeType().getLocalName() + "-" + UUID.randomUUID();
index c853124..e4f7b48 100644 (file)
@@ -19,6 +19,7 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.UUID;
 import org.opendaylight.controller.eos.akka.registry.listener.type.command.RegisterListener;
+import org.opendaylight.controller.eos.akka.registry.listener.type.command.TerminateListener;
 import org.opendaylight.controller.eos.akka.registry.listener.type.command.TypeListenerCommand;
 import org.opendaylight.controller.eos.akka.registry.listener.type.command.TypeListenerRegistryCommand;
 import org.opendaylight.controller.eos.akka.registry.listener.type.command.UnregisterListener;
@@ -65,7 +66,7 @@ public class EntityTypeListenerRegistry extends AbstractBehavior<TypeListenerReg
     private Behavior<TypeListenerRegistryCommand> onUnregisterListener(final UnregisterListener command) {
         LOG.debug("Stopping entity type listener actor for: {}", command.getEntityType());
 
-        getContext().stop(spawnedListenerActors.remove(command.getDelegateListener()));
+        spawnedListenerActors.remove(command.getDelegateListener()).tell(TerminateListener.INSTANCE);
         return this;
     }
 
diff --git a/opendaylight/md-sal/eos-dom-akka/src/main/java/org/opendaylight/controller/eos/akka/registry/listener/type/command/TerminateListener.java b/opendaylight/md-sal/eos-dom-akka/src/main/java/org/opendaylight/controller/eos/akka/registry/listener/type/command/TerminateListener.java
new file mode 100644 (file)
index 0000000..a2627e7
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.eos.akka.registry.listener.type.command;
+
+/**
+ * Sent to the listener actor to stop it on demand ie during listener unregistration.
+ */
+public final class TerminateListener extends TypeListenerCommand {
+
+    public static final TerminateListener INSTANCE = new TerminateListener();
+
+    private TerminateListener() {
+        // Hidden on purpose
+    }
+}