View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  
28  package org.apache.http.impl.nio.reactor;
29  
30  import org.apache.http.util.Args;
31  
32  /**
33   * I/O reactor configuration parameters.
34   *
35   * @since 4.2
36   */
37  public final class IOReactorConfig implements Cloneable {
38  
39      public static final IOReactorConfig DEFAULT = new Builder().build();
40  
41      // TODO: make final
42      private long selectInterval;
43      private long shutdownGracePeriod;
44      private boolean interestOpQueued;
45      private int ioThreadCount;
46      private int soTimeout;
47      private boolean soReuseAddress;
48      private int soLinger;
49      private boolean soKeepAlive;
50      private boolean tcpNoDelay;
51      private int connectTimeout;
52      private int sndBufSize;
53      private int rcvBufSize;
54      private final int backlogSize;
55  
56      @Deprecated
57      public IOReactorConfig() {
58          super();
59          this.selectInterval = 1000;
60          this.shutdownGracePeriod = 500;
61          this.interestOpQueued = false;
62          this.ioThreadCount = Builder.getDefaultMaxIoThreadCount();
63          this.soTimeout = 0;
64          this.soReuseAddress = false;
65          this.soLinger = -1;
66          this.soKeepAlive = false;
67          this.tcpNoDelay = true;
68          this.connectTimeout = 0;
69          this.sndBufSize = 0;
70          this.rcvBufSize = 0;
71          this.backlogSize = 0;
72      }
73  
74      IOReactorConfig(
75              final long selectInterval,
76              final long shutdownGracePeriod,
77              final boolean interestOpQueued,
78              final int ioThreadCount,
79              final int soTimeout,
80              final boolean soReuseAddress,
81              final int soLinger,
82              final boolean soKeepAlive,
83              final boolean tcpNoDelay,
84              final int connectTimeout,
85              final int sndBufSize,
86              final int rcvBufSize,
87              final int backlogSize) {
88          super();
89          this.selectInterval = selectInterval;
90          this.shutdownGracePeriod = shutdownGracePeriod;
91          this.interestOpQueued = interestOpQueued;
92          this.ioThreadCount = Args.positive(ioThreadCount, "ioThreadCount");
93          this.soTimeout = soTimeout;
94          this.soReuseAddress = soReuseAddress;
95          this.soLinger = soLinger;
96          this.soKeepAlive = soKeepAlive;
97          this.tcpNoDelay = tcpNoDelay;
98          this.connectTimeout = connectTimeout;
99          this.sndBufSize = sndBufSize;
100         this.rcvBufSize = rcvBufSize;
101         this.backlogSize = backlogSize;
102     }
103 
104     /**
105      * Determines time interval in milliseconds at which the I/O reactor wakes up to check for
106      * timed out sessions and session requests.
107      * <p>
108      * Default: {@code 1000} milliseconds.
109      */
110     public long getSelectInterval() {
111         return this.selectInterval;
112     }
113 
114     /**
115      * @deprecated (4.3) use {@link Builder#setSelectInterval(long)}
116      */
117     @Deprecated
118     public void setSelectInterval(final long selectInterval) {
119         Args.positive(selectInterval, "Select internal");
120         this.selectInterval = selectInterval;
121     }
122 
123     /**
124      * Determines grace period in milliseconds the I/O reactors are expected to block waiting
125      * for individual worker threads to terminate cleanly.
126      * <p>
127      * Default: {@code 500} milliseconds.
128      */
129     public long getShutdownGracePeriod() {
130         return this.shutdownGracePeriod;
131     }
132 
133     /**
134      * @deprecated (4.3) use {@link Builder#setShutdownGracePeriod(long)}
135      */
136     @Deprecated
137     public void setShutdownGracePeriod(final long gracePeriod) {
138         Args.positive(gracePeriod, "Shutdown grace period");
139         this.shutdownGracePeriod = gracePeriod;
140     }
141 
142     /**
143      * Determines whether or not I/O interest operations are to be queued and executed
144      * asynchronously by the I/O reactor thread or to be applied to the underlying
145      * {@link java.nio.channels.SelectionKey} immediately.
146      * <p>
147      * Default: {@code false}
148      *
149      * @see java.nio.channels.SelectionKey
150      * @see java.nio.channels.SelectionKey#interestOps()
151      * @see java.nio.channels.SelectionKey#interestOps(int)
152      */
153     public boolean isInterestOpQueued() {
154         return this.interestOpQueued;
155     }
156 
157     /**
158      * @deprecated (4.3) use {@link Builder#setInterestOpQueued(boolean)}
159      */
160     @Deprecated
161     public void setInterestOpQueued(final boolean interestOpQueued) {
162         this.interestOpQueued = interestOpQueued;
163     }
164 
165     /**
166      * Determines the number of I/O dispatch threads to be used by the I/O reactor.
167      * <p>
168      * Default: {@code 2}
169      */
170     public int getIoThreadCount() {
171         return this.ioThreadCount;
172     }
173 
174     /**
175      * @deprecated (4.3) use {@link Builder#setIoThreadCount(int)}
176      */
177     @Deprecated
178     public void setIoThreadCount(final int ioThreadCount) {
179         Args.positive(ioThreadCount, "I/O thread count");
180         this.ioThreadCount = ioThreadCount;
181     }
182 
183     /**
184      * Determines the default socket timeout value for non-blocking I/O operations.
185      * <p>
186      * Default: {@code 0} (no timeout)
187      *
188      * @see java.net.SocketOptions#SO_TIMEOUT
189      */
190     public int getSoTimeout() {
191         return soTimeout;
192     }
193 
194     /**
195      * @deprecated (4.3) use {@link Builder#setSoTimeout(int)}
196      */
197     @Deprecated
198     public void setSoTimeout(final int soTimeout) {
199         this.soTimeout = soTimeout;
200     }
201 
202     /**
203      * Determines the default value of the {@link java.net.SocketOptions#SO_REUSEADDR} parameter
204      * for newly created sockets.
205      * <p>
206      * Default: {@code false}
207      *
208      * @see java.net.SocketOptions#SO_REUSEADDR
209      */
210     public boolean isSoReuseAddress() {
211         return soReuseAddress;
212     }
213 
214     /**
215      * @deprecated (4.3) use {@link Builder#setSoReuseAddress(boolean)}
216      */
217     @Deprecated
218     public void setSoReuseAddress(final boolean soReuseAddress) {
219         this.soReuseAddress = soReuseAddress;
220     }
221 
222     /**
223      * Determines the default value of the {@link java.net.SocketOptions#SO_LINGER} parameter
224      * for newly created sockets.
225      * <p>
226      * Default: {@code -1}
227      *
228      * @see java.net.SocketOptions#SO_LINGER
229      */
230     public int getSoLinger() {
231         return soLinger;
232     }
233 
234     /**
235      * @deprecated (4.3) use {@link Builder#setSoLinger(int)}
236      */
237     @Deprecated
238     public void setSoLinger(final int soLinger) {
239         this.soLinger = soLinger;
240     }
241 
242     /**
243      * Determines the default value of the {@link java.net.SocketOptions#SO_KEEPALIVE} parameter
244      * for newly created sockets.
245      * <p>
246      * Default: {@code -1}
247      *
248      * @see java.net.SocketOptions#SO_KEEPALIVE
249      */
250     public boolean isSoKeepalive() {
251         return this.soKeepAlive;
252     }
253 
254     /**
255      * @deprecated (4.3) use {@link Builder#setSoKeepAlive(boolean)}
256      */
257     @Deprecated
258     public void setSoKeepalive(final boolean soKeepAlive) {
259         this.soKeepAlive = soKeepAlive;
260     }
261 
262     /**
263      * Determines the default value of the {@link java.net.SocketOptions#TCP_NODELAY} parameter
264      * for newly created sockets.
265      * <p>
266      * Default: {@code false}
267      *
268      * @see java.net.SocketOptions#TCP_NODELAY
269      */
270     public boolean isTcpNoDelay() {
271         return tcpNoDelay;
272     }
273 
274     /**
275      * @deprecated (4.3) use {@link Builder#setTcpNoDelay(boolean)}
276      */
277     @Deprecated
278     public void setTcpNoDelay(final boolean tcpNoDelay) {
279         this.tcpNoDelay = tcpNoDelay;
280     }
281 
282     /**
283      * Determines the default connect timeout value for non-blocking connection requests.
284      * <p>
285      * Default: {@code 0} (no timeout)
286      */
287     public int getConnectTimeout() {
288         return connectTimeout;
289     }
290 
291     /**
292      * @deprecated (4.3) use {@link Builder#setConnectTimeout(int)}
293      */
294     @Deprecated
295     public void setConnectTimeout(final int connectTimeout) {
296         this.connectTimeout = connectTimeout;
297     }
298 
299     /**
300      * Determines the default value of the {@link java.net.SocketOptions#SO_SNDBUF} parameter
301      * for newly created sockets.
302      * <p>
303      * Default: {@code 0} (system default)
304      *
305      * @see java.net.SocketOptions#SO_SNDBUF
306      */
307     public int getSndBufSize() {
308         return sndBufSize;
309     }
310 
311     /**
312      * @deprecated (4.3) use {@link Builder#setSndBufSize(int)}
313      */
314     @Deprecated
315     public void setSndBufSize(final int sndBufSize) {
316         this.sndBufSize = sndBufSize;
317     }
318 
319     /**
320      * Determines the default value of the {@link java.net.SocketOptions#SO_RCVBUF} parameter
321      * for newly created sockets.
322      * <p>
323      * Default: {@code 0} (system default)
324      *
325      * @see java.net.SocketOptions#SO_RCVBUF
326      */
327     public int getRcvBufSize() {
328         return rcvBufSize;
329     }
330 
331     /**
332      * @deprecated (4.3) use {@link Builder#setRcvBufSize(int)}
333      */
334     @Deprecated
335     public void setRcvBufSize(final int rcvBufSize) {
336         this.rcvBufSize = rcvBufSize;
337     }
338 
339     /**
340      * Determines the default backlog size value for server sockets binds.
341      * <p>
342      * Default: {@code 0} (system default)
343      *
344      * @since 4.4
345      */
346     public int getBacklogSize() {
347         return backlogSize;
348     }
349 
350     @Override
351     protected IOReactorConfig clone() throws CloneNotSupportedException {
352         return (IOReactorConfig) super.clone();
353     }
354 
355     public static Builder custom() {
356         return new Builder();
357     }
358 
359     public static Builder copy(final IOReactorConfig config) {
360         Args.notNull(config, "I/O reactor config");
361         return new Builder()
362             .setSelectInterval(config.getSelectInterval())
363             .setShutdownGracePeriod(config.getShutdownGracePeriod())
364             .setInterestOpQueued(config.isInterestOpQueued())
365             .setIoThreadCount(config.getIoThreadCount())
366             .setSoTimeout(config.getSoTimeout())
367             .setSoReuseAddress(config.isSoReuseAddress())
368             .setSoLinger(config.getSoLinger())
369             .setSoKeepAlive(config.isSoKeepalive())
370             .setTcpNoDelay(config.isTcpNoDelay())
371             .setConnectTimeout(config.getConnectTimeout())
372             .setSndBufSize(config.getSndBufSize())
373             .setRcvBufSize(config.getRcvBufSize())
374             .setBacklogSize(config.getBacklogSize());
375     }
376 
377     public static class Builder {
378 
379         private static int DefaultMaxIoThreadCount = -1;
380 
381         /**
382          * Gets the default value for {@code ioThreadCount}. Returns
383          * {@link Runtime#availableProcessors()} if
384          * {@link #setDefaultMaxIoThreadCount(int)} was called with a value <=0.
385          *
386          * @return the default value for ioThreadCount.
387          * @since 4.4.10
388          */
389         public static int getDefaultMaxIoThreadCount() {
390             return DefaultMaxIoThreadCount > 0 ? DefaultMaxIoThreadCount : Runtime.getRuntime().availableProcessors();
391         }
392 
393         /**
394          * Sets the default value for {@code ioThreadCount}. Use a value <= 0 to
395          * cause {@link #getDefaultMaxIoThreadCount()} to return
396          * {@link Runtime#availableProcessors()}.
397          *
398          * @param defaultMaxIoThreadCount
399          *            the default value for ioThreadCount.
400          * @since 4.4.10
401          */
402         public static void setDefaultMaxIoThreadCount(final int defaultMaxIoThreadCount) {
403             DefaultMaxIoThreadCount = defaultMaxIoThreadCount;
404         }
405 
406         private long selectInterval;
407         private long shutdownGracePeriod;
408         private boolean interestOpQueued;
409         private int ioThreadCount;
410         private int soTimeout;
411         private boolean soReuseAddress;
412         private int soLinger;
413         private boolean soKeepAlive;
414         private boolean tcpNoDelay;
415         private int connectTimeout;
416         private int sndBufSize;
417         private int rcvBufSize;
418         private int backlogSize;
419 
420         Builder() {
421             this.selectInterval = 1000;
422             this.shutdownGracePeriod = 500;
423             this.interestOpQueued = false;
424             this.ioThreadCount = getDefaultMaxIoThreadCount();
425             this.soTimeout = 0;
426             this.soReuseAddress = false;
427             this.soLinger = -1;
428             this.soKeepAlive = false;
429             this.tcpNoDelay = true;
430             this.connectTimeout = 0;
431             this.sndBufSize = 0;
432             this.rcvBufSize = 0;
433             this.backlogSize = 0;
434         }
435 
436         public Builder setSelectInterval(final long selectInterval) {
437             this.selectInterval = selectInterval;
438             return this;
439         }
440 
441         public Builder setShutdownGracePeriod(final long shutdownGracePeriod) {
442             this.shutdownGracePeriod = shutdownGracePeriod;
443             return this;
444         }
445 
446         public Builder setInterestOpQueued(final boolean interestOpQueued) {
447             this.interestOpQueued = interestOpQueued;
448             return this;
449         }
450 
451         public Builder setIoThreadCount(final int ioThreadCount) {
452             this.ioThreadCount = ioThreadCount;
453             return this;
454         }
455 
456         public Builder setSoTimeout(final int soTimeout) {
457             this.soTimeout = soTimeout;
458             return this;
459         }
460 
461         public Builder setSoReuseAddress(final boolean soReuseAddress) {
462             this.soReuseAddress = soReuseAddress;
463             return this;
464         }
465 
466         public Builder setSoLinger(final int soLinger) {
467             this.soLinger = soLinger;
468             return this;
469         }
470 
471         public Builder setSoKeepAlive(final boolean soKeepAlive) {
472             this.soKeepAlive = soKeepAlive;
473             return this;
474         }
475 
476         public Builder setTcpNoDelay(final boolean tcpNoDelay) {
477             this.tcpNoDelay = tcpNoDelay;
478             return this;
479         }
480 
481         public Builder setConnectTimeout(final int connectTimeout) {
482             this.connectTimeout = connectTimeout;
483             return this;
484         }
485 
486         public Builder setSndBufSize(final int sndBufSize) {
487             this.sndBufSize = sndBufSize;
488             return this;
489         }
490 
491         public Builder setRcvBufSize(final int rcvBufSize) {
492             this.rcvBufSize = rcvBufSize;
493             return this;
494         }
495 
496         public Builder setBacklogSize(final int backlogSize) {
497             this.backlogSize = backlogSize;
498             return this;
499         }
500 
501         public IOReactorConfig build() {
502             return new IOReactorConfig(
503                     selectInterval, shutdownGracePeriod, interestOpQueued, ioThreadCount,
504                     soTimeout, soReuseAddress, soLinger, soKeepAlive, tcpNoDelay,
505                     connectTimeout, sndBufSize, rcvBufSize, backlogSize);
506         }
507 
508     }
509 
510     @Override
511     public String toString() {
512         final StringBuilder builder = new StringBuilder();
513         builder.append("[selectInterval=").append(this.selectInterval)
514                 .append(", shutdownGracePeriod=").append(this.shutdownGracePeriod)
515                 .append(", interestOpQueued=").append(this.interestOpQueued)
516                 .append(", ioThreadCount=").append(this.ioThreadCount)
517                 .append(", soTimeout=").append(this.soTimeout)
518                 .append(", soReuseAddress=").append(this.soReuseAddress)
519                 .append(", soLinger=").append(this.soLinger)
520                 .append(", soKeepAlive=").append(this.soKeepAlive)
521                 .append(", tcpNoDelay=").append(this.tcpNoDelay)
522                 .append(", connectTimeout=").append(this.connectTimeout)
523                 .append(", sndBufSize=").append(this.sndBufSize)
524                 .append(", rcvBufSize=").append(this.rcvBufSize)
525                 .append(", backlogSize=").append(this.backlogSize)
526                 .append("]");
527         return builder.toString();
528     }
529 
530 }