Remove dmaap from models
[policy/models.git] / models-interactions / model-actors / actorServiceProvider / src / main / java / org / onap / policy / controlloop / actorserviceprovider / pipeline / FutureManager.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP
4  * ================================================================================
5  * Copyright (C) 2020 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20
21 package org.onap.policy.controlloop.actorserviceprovider.pipeline;
22
23 import java.util.HashMap;
24 import java.util.Map;
25 import java.util.concurrent.Future;
26 import lombok.NoArgsConstructor;
27
28 /**
29  * Manager that manages both futures and listeners. When {@link #stop()} is called, the
30  * listeners are executed and the futures are canceled. The various methods synchronize on
31  * "this" while they manipulate internal data structures.
32  */
33 @NoArgsConstructor
34 public class FutureManager extends ListenerManager {
35
36     /**
37      * Maps a future to its listener. Records the {@link Runnable} that is passed to
38      * {@link ListenerManager#add(Runnable)} when {@link #add(Future)} is invoked. This is
39      * needed if {@link #remove(Future)} is invoked, so that the same {@link Runnable} is
40      * used each time.
41      */
42     private final Map<Future<?>, Runnable> future2listener = new HashMap<>(5);
43
44     /**
45      * Adds a future that is to be canceled when this controller is stopped. Note: if the
46      * controller is already stopped, then the future will be canceled immediately, within
47      * the invoking thread.
48      *
49      * @param future future to be added
50      */
51     public <T> void add(Future<T> future) {
52         Runnable listener = () -> future.cancel(false);
53
54         synchronized (this) {
55             if (future2listener.putIfAbsent(future, listener) != null) {
56                 // this future is already in the map, nothing more to do
57                 return;
58             }
59
60             if (addOnly(listener)) {
61                 // successfully added
62                 return;
63             }
64         }
65
66         runListener(listener);
67     }
68
69     /**
70      * Removes a future so that it is not canceled when this controller is stopped.
71      *
72      * @param future future to be removed
73      */
74     public synchronized <T> void remove(Future<T> future) {
75         Runnable listener = future2listener.remove(future);
76         if (listener != null) {
77             remove(listener);
78         }
79     }
80
81     @Override
82     public void stop() {
83         super.stop();
84
85         synchronized (this) {
86             future2listener.clear();
87         }
88     }
89 }