/** * * Copyright 2018 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jivesoftware.smack; import java.util.Map; import java.util.Queue; import java.util.WeakHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Executor; /** * Helper class to perform an operation asynchronous but keeping the order in respect to a given key. *
* A typical use pattern for this helper class consists of callbacks for an abstract entity where the order of callbacks * matters, which eventually call user code in form of listeners. Since the order the callbacks matters, you need to use * synchronous connection listeners. But if those listeners would invoke the user provided listeners, and if those user * provided listeners would take a long time to complete, or even worse, block, then Smack's total progress is stalled, * since synchronous connection listeners are invoked from the main event loop. *
** It is common for those situations that the order of callbacks is not globally important, but only important in * respect to an particular entity. Take chat state notifications (CSN) for example: Assume there are two contacts which * send you CSNs. If a contact sends you first 'active' and then 'inactive, it is crucial that first the listener is * called with 'active' and afterwards with 'inactive'. But if there is another contact is sending 'composing' followed * by 'paused', then it is also important that the listeners are invoked in the correct order, but the order in which * the listeners for those two contacts are invoked does not matter. *
** Using this helper class, one would call {@link #performAsyncButOrdered(Object, Runnable)} which the remote contacts * JID as first argument and a {@link Runnable} invoking the user listeners as second. This class guarantees that * runnables of subsequent invocations are always executed after the runnables of previous invocations using the same * key. *
* * @param