001/**
002 * Copyright (C) 2012 FuseSource, Inc.
003 * http://fusesource.com
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *    http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018package org.fusesource.hawtdispatch;
019
020import org.fusesource.hawtdispatch.*;
021
022import java.nio.channels.SelectableChannel;
023import java.util.List;
024
025/**
026 * <p>
027 * The Dispatcher interface is used to get or create dispatch objects such
028 * as global queues, thread queues, serial queues, or dispatch sources.
029 * </p><p>
030 * The dispatch queues are {@link java.util.concurrent.Executor}
031 * objects that execute tasks asynchronously on thread pools managed by the
032 * Dispatcher.
033 *
034 * <ul>
035 * <li>
036 *   <b>Global Queues:</b> The tasks submitted to a concurrent dispatch
037 *   queue will execute concurrently on the first available thread of
038 *   the thread pool.  The order of execution of the tasks is non
039 *   deterministic.
040 * </li><li>
041 *   <b>Thread Queues:</b> The tasks submitted to a thread dispatch
042 *   queue will execute serially (FIFO order) on a single thread of
043 *   the thread pool.
044 * </li><li>
045 *   <b>Serial Queues:</b> The tasks submitted to a serial dispatch
046 *   queue will execute serially (FIFO order) on the first available
047 *   thread of the thread pool.
048 * </li>
049 * </p><p>
050 * All dispatch queues use a shared fixed size thread pool to execute
051 * tasks.  All tasks submitted on a dispatch queue should be non-blocking
052 * and wait free.
053 * </p><p>
054 * Dispatch sources provide a way to trigger execution of a user task on
055 * on a user selected dispatch queue in response to NIO or application
056 * defined events.
057 * </p>
058 *
059 * @author <a href="http://hiramchirino.com">Hiram Chirino</a>
060 */
061public interface Dispatcher {
062
063    /**
064     * @return the thread level dispatch queues for a given dispatch priority.
065     */
066    public DispatchQueue[] getThreadQueues(DispatchPriority priority);
067
068    /**
069     *
070     * @return the current thread queue or null of not executing on a thread queue.
071     */
072    public DispatchQueue getCurrentThreadQueue();
073
074    /**
075     * <p>
076     * Returns the global concurrent queue of default priority.
077     * </p>
078     *
079     * @see #getGlobalQueue(DispatchPriority)
080     * @return the default priority global queue.
081     */
082    public DispatchQueue getGlobalQueue();
083
084    /**
085     * <p>
086     * Returns a well-known global concurrent queue of a given priority level.
087     * </p><p>
088     * The well-known global concurrent queues may not be modified. Calls to
089     * {@link Suspendable#suspend()}, {@link Suspendable#resume()}, etc., will
090     * have no effect when used with queues returned by this function.
091     * </p>
092     *
093     * @param priority
094     * A priority defined in dispatch_queue_priority_t
095     * @return the requested global queue.
096     */
097    public DispatchQueue getGlobalQueue(DispatchPriority priority);
098    
099    /**
100     * <p>
101     * Creates a new serial dispatch queue to which runnable objects may be submitted.
102     * </p><p>
103     * Serial dispatch queues execute runnables submitted to them serially in FIFO order. A
104     * queue will only invoke one runnable at a time, but independent queues may each
105     * execute their runnables concurrently with respect to each other.
106     * </p><p>
107     * Conceptually a dispatch queue may have its own thread of execution, and
108     * interaction between queues is highly asynchronous.
109     * </p>
110     *
111     * @param label the label to assign the dispatch queue, can be null
112     * @return the newly created dispatch queue
113     */
114    public DispatchQueue createQueue(String label);
115    
116//    public DispatchQueue getMainQueue();
117//    public void dispatchMain();
118    
119    /**
120     * <p>
121     * Returns the queue on which the currently executing runnable is running.
122     * </p><p>
123     * When {@link #getCurrentQueue()} is called outside of the context of a
124     * submitted runnable, it will return null.
125     * </p>
126     *
127     * @return the queue on which the currently executing runnable is running.
128     */
129    public DispatchQueue getCurrentQueue();
130
131    /**
132     * <p>
133     * Creates a new {@link DispatchSource} to monitor {@link SelectableChannel} objects and
134     * automatically submit a handler runnable to a dispatch queue in response to events.
135     * </p><p>
136     * You are allowed to create multiple dispatch sources to the same {@link SelectableChannel}
137     * object.
138     * </p>
139     *
140     * @param channel the channel to monitor.
141     * @param interestOps A mask of interest ops ({@link java.nio.channels.SelectionKey#OP_ACCEPT},
142     *        {@link java.nio.channels.SelectionKey#OP_CONNECT}, {@link java.nio.channels.SelectionKey#OP_READ}, or
143     *        {@link java.nio.channels.SelectionKey#OP_WRITE}) specifying which events are desired.
144     * @param queue The dispatch queue to which the event handler tasks will be submited.
145     *
146     * @return the newly created DispatchSource
147     */
148    public DispatchSource createSource(SelectableChannel channel, int interestOps, DispatchQueue queue);
149
150    /**
151     * <p>
152     * Creates a new {@link CustomDispatchSource} to monitor events merged into
153     * the dispatch source and automatically submit a handler runnable to a dispatch queue
154     * in response to the events.
155     * </p>
156     *
157     * @param aggregator the data aggregation strategy to use.
158     * @param queue The dispatch queue to which the event handler tasks will be submited.
159     *
160     * @return the newly created CustomDispatchSource
161     */
162    public <Event, MergedEvent> CustomDispatchSource<Event, MergedEvent> createSource(EventAggregator<Event, MergedEvent> aggregator, DispatchQueue queue);
163
164    /**
165     * If enabled then it enables profiling on the global
166     * queues and any newly created queues.  If not enabled
167     * then it disables profiling support on all the currently
168     * profiled queues and any queues created in the future.
169     *
170     * @param enabled
171     */
172    public void profile(boolean enabled);
173
174    /**
175     * @return true is profiling is enabled.
176     */
177    public boolean profile();
178
179    /**
180     * Used to get profiling metrics for all the queues
181     * currently being profiled.
182     *
183     * @return
184     */
185    public List<Metrics> metrics();
186
187    /**
188     * Shutdown this dispatcher instance.
189     */
190    public void shutdown();
191
192    /**
193     * Restart this dispatcher instance.
194     */
195    public void restart();
196}