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    
018    package org.fusesource.hawtdispatch;
019    
020    import org.fusesource.hawtdispatch.*;
021    
022    import java.nio.channels.SelectableChannel;
023    import 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     */
061    public 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         * Used to get profiling metrics for all the queues
176         * currently being profiled.
177         *
178         * @return
179         */
180        public List<Metrics> metrics();
181    
182    }