Migrate Queue stats collection
[yangtools.git] / common / util / src / main / java / org / opendaylight / yangtools / util / concurrent / AbstractQueuedNotificationManager.java
1 /*
2  * Copyright (c) 2014 Brocade Communications Systems, Inc. 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.yangtools.util.concurrent;
9
10 import static java.util.Objects.requireNonNull;
11
12 import com.google.common.collect.ImmutableList;
13 import java.util.concurrent.Executor;
14 import org.eclipse.jdt.annotation.NonNull;
15 import org.eclipse.jdt.annotation.NonNullByDefault;
16 import org.eclipse.jdt.annotation.Nullable;
17 import org.opendaylight.yangtools.util.concurrent.QueuedNotificationManager.BatchedInvoker;
18
19 /**
20  * This class manages queuing and dispatching notifications for multiple listeners concurrently.
21  * Notifications are queued on a per-listener basis and dispatched serially to each listener via an
22  * {@link Executor}.
23  *
24  * <p>This class optimizes its memory footprint by only allocating and maintaining a queue and executor
25  * task for a listener when there are pending notifications. On the first notification(s), a queue
26  * is created and a task is submitted to the executor to dispatch the queue to the associated
27  * listener. Any subsequent notifications that occur before all previous notifications have been
28  * dispatched are appended to the existing queue. When all notifications have been dispatched, the
29  * queue and task are discarded.
30  *
31  * @author Thomas Pantelis
32  *
33  * @param <L> the listener type
34  * @param <N> the notification type
35  */
36 @NonNullByDefault
37 abstract class AbstractQueuedNotificationManager<T, L, N> extends AbstractBatchingExecutor<T, N>
38         implements NotificationManager<L, N> {
39
40     private final QueuedNotificationManagerMXBean mxBean = new QueuedNotificationManagerMXBeanImpl(this);
41     private final BatchedInvoker<L, N> listenerInvoker;
42
43     AbstractQueuedNotificationManager(final String name, final Executor executor, final int maxQueueCapacity,
44             final BatchedInvoker<L, N> listenerInvoker) {
45         super(name, executor, maxQueueCapacity);
46         this.listenerInvoker = requireNonNull(listenerInvoker);
47     }
48
49     /**
50      * Returns the {@link Executor} to used for notification tasks.
51      */
52     public final Executor getExecutor() {
53         return executor();
54     }
55
56     /**
57      * Returns the maximum listener queue capacity.
58      */
59     public final int getMaxQueueCapacity() {
60         return maxQueueCapacity();
61     }
62
63     /**
64      * Return an {@link QueuedNotificationManagerMXBean} tied to this instance.
65      *
66      * @return An QueuedNotificationManagerMXBean object.
67      */
68     public final QueuedNotificationManagerMXBean getMXBean() {
69         return mxBean;
70     }
71
72     @Override
73     public final void submitNotification(final L listener, final N notification) {
74         if (listener != null && notification != null) {
75             submitTask(wrap(listener), notification);
76         }
77     }
78
79     @Override
80     public final void submitNotifications(final L listener, final @Nullable Iterable<N> notifications) {
81         if (listener != null && notifications != null) {
82             submitTasks(wrap(listener), notifications);
83         }
84     }
85
86     @Override
87     final void executeBatch(final T key, final @NonNull ImmutableList<N> tasks) {
88         listenerInvoker.invokeListener(unwrap(key), tasks);
89     }
90
91     abstract T wrap(L listener);
92
93     abstract L unwrap(T key);
94 }