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