Add UnsignedLongBitmap
[controller.git] / opendaylight / md-sal / sal-distributed-datastore / src / main / java / org / opendaylight / controller / cluster / datastore / actors / DataTreeNotificationListenerRegistrationActor.java
1 /*
2  * Copyright (c) 2017 Inocybe Technologies and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.controller.cluster.datastore.actors;
9
10 import static java.util.Objects.requireNonNull;
11
12 import akka.actor.ActorRef;
13 import akka.actor.Cancellable;
14 import akka.actor.PoisonPill;
15 import akka.actor.Props;
16 import com.google.common.annotations.VisibleForTesting;
17 import java.util.concurrent.TimeUnit;
18 import org.opendaylight.controller.cluster.common.actor.AbstractUntypedActor;
19 import org.opendaylight.controller.cluster.datastore.messages.CloseDataTreeNotificationListenerRegistration;
20 import org.opendaylight.controller.cluster.datastore.messages.CloseDataTreeNotificationListenerRegistrationReply;
21 import org.opendaylight.yangtools.concepts.ListenerRegistration;
22 import scala.concurrent.duration.FiniteDuration;
23
24 /**
25  * Actor co-located with a shard. It exists only to terminate the registration when
26  * asked to do so via {@link CloseDataTreeNotificationListenerRegistration}.
27  */
28 public final class DataTreeNotificationListenerRegistrationActor extends AbstractUntypedActor {
29     // FIXME: rework this constant to a duration and its injection
30     @VisibleForTesting
31     static long killDelay = TimeUnit.MILLISECONDS.convert(5, TimeUnit.SECONDS);
32
33     private ListenerRegistration<?> registration;
34     private Runnable onClose;
35     private boolean closed;
36     private Cancellable killSchedule;
37
38     @Override
39     protected void handleReceive(final Object message) {
40         if (message instanceof CloseDataTreeNotificationListenerRegistration) {
41             closeListenerRegistration();
42             if (isValidSender(getSender())) {
43                 getSender().tell(CloseDataTreeNotificationListenerRegistrationReply.getInstance(), getSelf());
44             }
45         } else if (message instanceof SetRegistration) {
46             registration = ((SetRegistration)message).registration;
47             onClose = ((SetRegistration)message).onClose;
48             if (closed) {
49                 closeListenerRegistration();
50             }
51         } else {
52             unknownMessage(message);
53         }
54     }
55
56     private void closeListenerRegistration() {
57         closed = true;
58         if (registration != null) {
59             registration.close();
60             onClose.run();
61             registration = null;
62
63             if (killSchedule == null) {
64                 killSchedule = getContext().system().scheduler().scheduleOnce(FiniteDuration.create(killDelay,
65                         TimeUnit.MILLISECONDS), getSelf(), PoisonPill.getInstance(), getContext().dispatcher(),
66                         ActorRef.noSender());
67             }
68         }
69     }
70
71     public static Props props() {
72         return Props.create(DataTreeNotificationListenerRegistrationActor.class);
73     }
74
75     public static class SetRegistration {
76         private final ListenerRegistration<?> registration;
77         private final Runnable onClose;
78
79         public SetRegistration(final ListenerRegistration<?> registration, final Runnable onClose) {
80             this.registration = requireNonNull(registration);
81             this.onClose = requireNonNull(onClose);
82         }
83     }
84 }