View Javadoc

1   /*
2    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3    *
4    * Copyright (c) 2007-2010 Oracle and/or its affiliates. All rights reserved.
5    *
6    * The contents of this file are subject to the terms of either the GNU
7    * General Public License Version 2 only ("GPL") or the Common Development
8    * and Distribution License("CDDL") (collectively, the "License").  You
9    * may not use this file except in compliance with the License.  You can
10   * obtain a copy of the License at
11   * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
12   * or packager/legal/LICENSE.txt.  See the License for the specific
13   * language governing permissions and limitations under the License.
14   *
15   * When distributing the software, include this License Header Notice in each
16   * file and include the License file at packager/legal/LICENSE.txt.
17   *
18   * GPL Classpath Exception:
19   * Oracle designates this particular file as subject to the "Classpath"
20   * exception as provided by Oracle in the GPL Version 2 section of the License
21   * file that accompanied this code.
22   *
23   * Modifications:
24   * If applicable, add the following below the License Header, with the fields
25   * enclosed by brackets [] replaced by your own identifying information:
26   * "Portions Copyright [year] [name of copyright owner]"
27   *
28   * Contributor(s):
29   * If you wish your version of this file to be governed by only the CDDL or
30   * only the GPL Version 2, indicate your decision by adding "[Contributor]
31   * elects to include this software in this distribution under the [CDDL or GPL
32   * Version 2] license."  If you don't indicate a single choice of license, a
33   * recipient has the option to distribute your version of this file under
34   * either the CDDL, the GPL Version 2 or to extend the choice of license to
35   * its licensees as provided above.  However, if you add GPL Version 2 code
36   * and therefore, elected the GPL Version 2 license, then the option applies
37   * only if the new code is made subject to such option by the copyright
38   * holder.
39   */
40  
41  package com.sun.grizzly.async;
42  
43  import com.sun.grizzly.SelectorHandler;
44  
45  import java.io.IOException;
46  import java.net.SocketAddress;
47  import java.nio.ByteBuffer;
48  import java.nio.channels.SelectableChannel;
49  import java.nio.channels.SelectionKey;
50  import java.util.concurrent.Future;
51  
52  /**
53   * Common interface to be implemented by protocol dependant asynchronous queue
54   * writers implementations
55   * 
56   * @author Alexey Stashok
57   */
58  public interface AsyncQueueWriter {
59      /**
60       * Method writes {@link ByteBuffer} to the {@link SelectableChannel}
61       * First, if {@link SelectableChannel} associated write queue is empty -
62       * it tries to write {@link ByteBuffer} to the given 
63       * {@link SelectableChannel} directly (without putting to the queue).
64       * If associated write queue is not empty or after direct writing 
65       * {@link ByteBuffer} still has ready data to be written - 
66       * {@link ByteBuffer} will be added to {@link AsyncQueue} 
67       * and {@link SelectableChannel} will be registered on 
68       * {@link SelectorHandler}, waiting for OP_WRITE event.
69       * If an exception occurs, during direct writing - it will be propagated 
70       * to the caller directly, otherwise it will be just logged by 
71       * Grizzly framework.
72       * 
73       * @param key {@link SelectionKey} associated with 
74       *            {@link SelectableChannel} {@link ByteBuffer} 
75       *            should be written to
76       * @param buffer {@link ByteBuffer}
77       * @throws IOException
78       */
79      Future<AsyncQueueWriteUnit> write(SelectionKey key,
80              ByteBuffer buffer) throws IOException;
81      
82      /**
83       * Method writes {@link ByteBuffer} to the {@link SelectableChannel}
84       * First, if {@link SelectableChannel} associated write queue is empty -
85       * it tries to write {@link ByteBuffer} to the given 
86       * {@link SelectableChannel} directly (without putting to the queue).
87       * If associated write queue is not empty or after direct writing 
88       * {@link ByteBuffer} still has ready data to be written - 
89       * {@link ByteBuffer} will be added to {@link AsyncQueue} 
90       * and {@link SelectableChannel} will be registered on 
91       * {@link SelectorHandler}, waiting for OP_WRITE event.
92       * If an exception occurs, during direct writing - it will be propagated 
93       * to the caller directly and come via
94       * <code>AsyncWriteCallbackHandler.onIOException()</code>
95       * 
96       * @param key {@link SelectionKey} associated with 
97       *            {@link SelectableChannel} {@link ByteBuffer} 
98       *            should be written to
99       * @param buffer {@link ByteBuffer}
100      * @param callbackHandler {@link AsyncWriteCallbackHandler}, 
101      *                        which will get notified, when 
102      *                        {@link ByteBuffer} will be completely written
103      * @throws IOException
104      */
105     Future<AsyncQueueWriteUnit> write(SelectionKey key,
106             ByteBuffer buffer,
107             AsyncWriteCallbackHandler callbackHandler) throws IOException;
108 
109     /**
110      * Method writes {@link ByteBuffer} to the {@link SelectableChannel}
111      * First, if {@link SelectableChannel} associated write queue is empty -
112      * it tries to write {@link ByteBuffer} to the given 
113      * {@link SelectableChannel} directly (without putting to the queue).
114      * If associated write queue is not empty or after direct writing 
115      * {@link ByteBuffer} still has ready data to be written - 
116      * {@link ByteBuffer} will be added to {@link AsyncQueue} 
117      * and {@link SelectableChannel} will be registered on 
118      * {@link SelectorHandler}, waiting for OP_WRITE event.
119      * If an exception occurs, during direct writing - it will be propagated 
120      * to the caller directly and come via
121      * <code>AsyncWriteCallbackHandler.onIOException()</code>
122      * Before data will be written on {@link SelectableChannel}, first it
123      * will be passed for preprocessing to <code>AsyncQueueDataProcessor</code>,
124      * and then preprocessor result data 
125      * (<code>AsyncQueueDataProcessor.getResultByteBuffer()</code>) will be 
126      * written on the {@link SelectableChannel}.
127      * 
128      * @param key {@link SelectionKey} associated with 
129      *            {@link SelectableChannel} {@link ByteBuffer} 
130      *            should be written to
131      * @param buffer {@link ByteBuffer}
132      * @param callbackHandler {@link AsyncWriteCallbackHandler}, 
133      *                        which will get notified, when 
134      *                        {@link ByteBuffer} will be completely written
135      * @param writePreProcessor <code>AsyncQueueDataProcessor</code>, which
136      *                        will perform data processing, before it will be 
137      *                        written on {@link SelectableChannel}
138      * @throws IOException
139      */
140     Future<AsyncQueueWriteUnit> write(SelectionKey key,
141             ByteBuffer buffer, AsyncWriteCallbackHandler callbackHandler,
142             AsyncQueueDataProcessor writePreProcessor) throws IOException;
143 
144     /**
145      * Method writes {@link ByteBuffer} to the {@link SelectableChannel}
146      * First, if {@link SelectableChannel} associated write queue is empty -
147      * it tries to write {@link ByteBuffer} to the given 
148      * {@link SelectableChannel} directly (without putting to the queue).
149      * If associated write queue is not empty or after direct writing 
150      * {@link ByteBuffer} still has ready data to be written - 
151      * {@link ByteBuffer} will be added to {@link AsyncQueue} 
152      * and {@link SelectableChannel} will be registered on 
153      * {@link SelectorHandler}, waiting for OP_WRITE event.
154      * If an exception occurs, during direct writing - it will be propagated 
155      * to the caller directly and come via
156      * <code>AsyncWriteCallbackHandler.onIOException()</code>
157      * Before data will be written on {@link SelectableChannel}, first it
158      * will be passed for preprocessing to <code>AsyncQueueDataProcessor</code>,
159      * and then preprocessor result data 
160      * (<code>AsyncQueueDataProcessor.getResultByteBuffer()</code>) will be 
161      * written on the {@link SelectableChannel}.
162      * 
163      * @param key {@link SelectionKey} associated with 
164      *            {@link SelectableChannel} {@link ByteBuffer} 
165      *            should be written to
166      * @param buffer {@link ByteBuffer}
167      * @param callbackHandler {@link AsyncWriteCallbackHandler}, 
168      *                        which will get notified, when 
169      *                        {@link ByteBuffer} will be completely written
170      * @param writePreProcessor <code>AsyncQueueDataProcessor</code>, which
171      *                        will perform data processing, before it will be 
172      *                        written on {@link SelectableChannel}
173      * @throws IOException
174      */
175     Future<AsyncQueueWriteUnit> write(SelectionKey key,
176             ByteBuffer buffer, AsyncWriteCallbackHandler callbackHandler,
177             AsyncQueueDataProcessor writePreProcessor, ByteBufferCloner cloner)
178             throws IOException;
179 
180     /**
181      * Method sends {@link ByteBuffer} to the {@link SocketAddress}
182      * First, if {@link SelectableChannel} associated write queue is empty -
183      * it tries to write {@link ByteBuffer} to the given 
184      * {@link SocketAddress} directly (without putting to the queue).
185      * If associated write queue is not empty or after direct writing 
186      * {@link ByteBuffer} still has ready data to be written - 
187      * {@link ByteBuffer} will be added to {@link AsyncQueue} 
188      * and {@link SelectableChannel} will be registered on 
189      * {@link SelectorHandler}, waiting for OP_WRITE event.
190      * If an exception occurs, during direct writing - it will be propagated 
191      * to the caller directly, otherwise it will be just logged by 
192      * Grizzly framework.
193      * 
194      * @param key {@link SelectionKey} associated with 
195      *            {@link SelectableChannel}, which will be used to
196      *            send{@link ByteBuffer} to
197      * @param dstAddress destination address {@link ByteBuffer} will be sent to
198      * @param buffer {@link ByteBuffer}
199      * @throws IOException
200      */
201     Future<AsyncQueueWriteUnit> write(SelectionKey key,
202             SocketAddress dstAddress, ByteBuffer buffer) throws IOException;
203     
204     /**
205      * Method sends {@link ByteBuffer} to the {@link SocketAddress}
206      * First, if {@link SelectableChannel} associated write queue is empty -
207      * it tries to write {@link ByteBuffer} to the given 
208      * {@link SocketAddress} directly (without putting to the queue).
209      * If associated write queue is not empty or after direct writing 
210      * {@link ByteBuffer} still has ready data to be written - 
211      * {@link ByteBuffer} will be added to {@link AsyncQueue} 
212      * and {@link SelectableChannel} will be registered on 
213      * {@link SelectorHandler}, waiting for OP_WRITE event.
214      * If an exception occurs, during direct writing - it will be propagated 
215      * to the caller directly and come via
216      * <code>AsyncWriteCallbackHandler.onIOException()</code>
217      * 
218      * @param key {@link SelectionKey} associated with 
219      *            {@link SelectableChannel} {@link ByteBuffer} 
220      *            should be written to
221      * @param dstAddress destination address {@link ByteBuffer} will be sent to
222      * @param buffer {@link ByteBuffer}
223      * @param callbackHandler {@link AsyncWriteCallbackHandler}, 
224      *                        which will get notified, when 
225      *                        {@link ByteBuffer} will be completely written
226      * @throws IOException
227      */
228     Future<AsyncQueueWriteUnit> write(SelectionKey key,
229             SocketAddress dstAddress, ByteBuffer buffer,
230             AsyncWriteCallbackHandler callbackHandler) throws IOException;
231 
232     /**
233      * Method sends {@link ByteBuffer} to the {@link SocketAddress}
234      * First, if {@link SelectableChannel} associated write queue is empty -
235      * it tries to write {@link ByteBuffer} to the given 
236      * {@link SocketAddress} directly (without putting to the queue).
237      * If associated write queue is not empty or after direct writing 
238      * {@link ByteBuffer} still has ready data to be written - 
239      * {@link ByteBuffer} will be added to {@link AsyncQueue} 
240      * and {@link SelectableChannel} will be registered on 
241      * {@link SelectorHandler}, waiting for OP_WRITE event.
242      * If an exception occurs, during direct writing - it will be propagated 
243      * to the caller directly and come via
244      * <code>AsyncWriteCallbackHandler.onIOException()</code>
245      * Before data will be written on {@link SelectableChannel}, first it
246      * will be passed for preprocessing to <code>AsyncQueueDataProcessor</code>,
247      * and then preprocessor result data 
248      * (<code>AsyncQueueDataProcessor.getResultByteBuffer()</code>) will be 
249      * written on the {@link SelectableChannel}.
250      * 
251      * @param key {@link SelectionKey} associated with 
252      *            {@link SelectableChannel} {@link ByteBuffer} 
253      *            should be written to
254      * @param dstAddress destination address {@link ByteBuffer} will be sent to
255      * @param buffer {@link ByteBuffer}
256      * @param callbackHandler {@link AsyncWriteCallbackHandler}, 
257      *                        which will get notified, when 
258      *                        {@link ByteBuffer} will be completely written
259      * @param writePreProcessor <code>AsyncQueueDataProcessor</code>, which
260      *                        will perform data processing, before it will be 
261      *                        written on {@link SelectableChannel}
262      * @throws IOException
263      */
264     Future<AsyncQueueWriteUnit> write(SelectionKey key,
265             SocketAddress dstAddress,
266             ByteBuffer buffer, AsyncWriteCallbackHandler callbackHandler,
267             AsyncQueueDataProcessor writePreProcessor) throws IOException;
268 
269     /**
270      * Method sends {@link ByteBuffer} to the {@link SocketAddress}
271      * First, if {@link SelectableChannel} associated write queue is empty -
272      * it tries to write {@link ByteBuffer} to the given 
273      * {@link SocketAddress} directly (without putting to the queue).
274      * If associated write queue is not empty or after direct writing 
275      * {@link ByteBuffer} still has ready data to be written - 
276      * {@link ByteBuffer} will be added to {@link AsyncQueue} 
277      * and {@link SelectableChannel} will be registered on 
278      * {@link SelectorHandler}, waiting for OP_WRITE event.
279      * If an exception occurs, during direct writing - it will be propagated 
280      * to the caller directly and come via
281      * <code>AsyncWriteCallbackHandler.onIOException()</code>
282      * Before data will be written on {@link SelectableChannel}, first it
283      * will be passed for preprocessing to <code>AsyncQueueDataProcessor</code>,
284      * and then preprocessor result data 
285      * (<code>AsyncQueueDataProcessor.getResultByteBuffer()</code>) will be 
286      * written on the {@link SelectableChannel}.
287      * 
288      * @param key {@link SelectionKey} associated with 
289      *            {@link SelectableChannel} {@link ByteBuffer} 
290      *            should be written to
291      * @param dstAddress destination address {@link ByteBuffer} will be sent to
292      * @param buffer {@link ByteBuffer}
293      * @param callbackHandler {@link AsyncWriteCallbackHandler}, 
294      *                        which will get notified, when 
295      *                        {@link ByteBuffer} will be completely written
296      * @param writePreProcessor <code>AsyncQueueDataProcessor</code>, which
297      *                        will perform data processing, before it will be 
298      *                        written on {@link SelectableChannel}
299      * @throws IOException
300      */
301     Future<AsyncQueueWriteUnit> write(SelectionKey key,
302             SocketAddress dstAddress, ByteBuffer buffer,
303             AsyncWriteCallbackHandler callbackHandler,
304             AsyncQueueDataProcessor writePreProcessor,
305             ByteBufferCloner cloner)
306             throws IOException;
307 
308     /**
309      * Checks whether there is any data in {@link AsyncQueue} ready
310      * to be written to the {@link SelectableChannel}, associated with the
311      * given {@link SelectionKey}
312      * 
313      * @param key {@link SelectionKey} associated with {@link SelectableChannel}
314      * @return true, if there is ready data. False otherwise.
315      */
316     boolean isReady(SelectionKey key);
317     
318     /**
319      * Gets ready asynchronous queue elements to be written to the
320      * {@link SelectableChannel}, associated with the
321      * given {@link SelectionKey}
322      *
323      * @param key {@link SelectionKey} associated with {@link SelectableChannel}
324      * @return ready asynchronous queue elements to be written to the
325      * {@link SelectableChannel}, associated with the
326      * given {@link SelectionKey}/
327      */
328     AsyncQueue.AsyncQueueEntry getAsyncQueue(SelectionKey key);
329 
330     /**
331      * Callback method, which should be called by {@link SelectorHandler} to
332      * notify, that {@link SelectableChannel}, associated with the given 
333      * {@link SelectionKey} is ready to transmit data.
334      * 
335      * @param key {@link SelectionKey} associated with {@link SelectableChannel}
336      * @throws IOException
337      */
338     void onWrite(SelectionKey key) throws IOException;
339     
340     /**
341      * Callback method, which should be called by {@link SelectorHandler} to
342      * notify, that given {@link SelectableChannel} is going to be closed, so
343      * related {@link SelectableChannel} data could be released from 
344      * {@link AsyncQueue}
345      * 
346      * @param {@link SelectableChannel}
347      * @throws IOException
348      */
349     void onClose(SelectableChannel channel);
350     
351     /**
352      * Close {@link AsyncQueueWriter} and release its resources
353      */
354     void close();
355 }