/*
 * Copyright (c) 2011, 2017 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package org.glassfish.grizzly;

import java.nio.channels.spi.SelectorProvider;
import java.util.concurrent.TimeUnit;

import org.glassfish.grizzly.asyncqueue.AsyncQueueWriter;
import org.glassfish.grizzly.attributes.AttributeBuilder;
import org.glassfish.grizzly.memory.MemoryManager;
import org.glassfish.grizzly.nio.NIOChannelDistributor;
import org.glassfish.grizzly.nio.NIOTransport;
import org.glassfish.grizzly.nio.SelectionKeyHandler;
import org.glassfish.grizzly.nio.SelectorHandler;
import org.glassfish.grizzly.strategies.WorkerThreadIOStrategy;
import org.glassfish.grizzly.threadpool.ThreadPoolConfig;

This builder is responsible for creating NIOTransport implementations as well as providing basic configuration for IOStrategies and thread pools.
See Also:
Since:2.0
/** * This builder is responsible for creating {@link NIOTransport} implementations * as well as providing basic configuration for <code>IOStrategies</code> and * thread pools. * * @see NIOTransport * @see IOStrategy * @see ThreadPoolConfig * * @since 2.0 */
@SuppressWarnings("UnusedDeclaration") public abstract class NIOTransportBuilder<T extends NIOTransportBuilder> { protected final Class<? extends NIOTransport> transportClass; protected ThreadPoolConfig workerConfig; protected ThreadPoolConfig kernelConfig; protected SelectorProvider selectorProvider; protected SelectorHandler selectorHandler = SelectorHandler.DEFAULT_SELECTOR_HANDLER; protected SelectionKeyHandler selectionKeyHandler = SelectionKeyHandler.DEFAULT_SELECTION_KEY_HANDLER; protected MemoryManager memoryManager = MemoryManager.DEFAULT_MEMORY_MANAGER; protected AttributeBuilder attributeBuilder = AttributeBuilder.DEFAULT_ATTRIBUTE_BUILDER; protected IOStrategy ioStrategy = WorkerThreadIOStrategy.getInstance(); protected int selectorRunnerCount = NIOTransport.DEFAULT_SELECTOR_RUNNER_COUNT; protected NIOChannelDistributor nioChannelDistributor; protected String name; protected Processor processor; protected ProcessorSelector processorSelector; protected int readBufferSize = Transport.DEFAULT_READ_BUFFER_SIZE; protected int writeBufferSize = Transport.DEFAULT_WRITE_BUFFER_SIZE; protected int clientSocketSoTimeout = NIOTransport.DEFAULT_CLIENT_SOCKET_SO_TIMEOUT; protected int connectionTimeout = NIOTransport.DEFAULT_CONNECTION_TIMEOUT; protected boolean reuseAddress = NIOTransport.DEFAULT_REUSE_ADDRESS; protected int maxPendingBytesPerConnection = AsyncQueueWriter.AUTO_SIZE; protected boolean optimizedForMultiplexing = NIOTransport.DEFAULT_OPTIMIZED_FOR_MULTIPLEXING; protected long readTimeout = TimeUnit.MILLISECONDS.convert(Transport.DEFAULT_READ_TIMEOUT, TimeUnit.SECONDS); protected long writeTimeout = TimeUnit.MILLISECONDS.convert(Transport.DEFAULT_WRITE_TIMEOUT, TimeUnit.SECONDS); // ------------------------------------------------------------ Constructors

Constructs a new NIOTransport using the given transportClass and IOStrategy.

The builder's worker thread pool configuration will be based on the return value of WorkerThreadPoolConfigProducer.createDefaultWorkerPoolConfig(Transport). If worker thread configuration is non-null, the initial selector thread pool configuration will be cloned from it, otherwise a default configuration will be chosen.

Params:
  • transportClass – the class of the NIOTransport implementation to be used.
/** * <p> * Constructs a new <code>NIOTransport</code> using the given * <code>transportClass</code> and {@link IOStrategy}. * </p> * * <p> * The builder's worker thread pool configuration will be based on the return * value of {@link IOStrategy#createDefaultWorkerPoolConfig(Transport)}. * If worker thread configuration is non-null, the initial selector thread pool * configuration will be cloned from it, otherwise a default configuration * will be chosen. * </p> * * @param transportClass the class of the {@link NIOTransport} * implementation to be used. */
protected NIOTransportBuilder(final Class<? extends NIOTransport> transportClass) { this.transportClass = transportClass; } // ---------------------------------------------------------- Public Methods
Returns:the number of Selectors to be created to serve Transport connections. -1 is the default value, which lets the Transport to pick the value, usually it's equal to the number of CPU cores Runtime.availableProcessors()
/** * @return the number of {@link Selector}s to be created to serve Transport * connections. <tt>-1</tt> is the default value, which lets the Transport * to pick the value, usually it's equal to the number of CPU cores * {@link Runtime#availableProcessors()} */
public int getSelectorRunnersCount() { return selectorRunnerCount; }
Sets the number of Selectors to be created to serve Transport connections. -1 is the default value, which lets the Transport to pick the value, usually it's equal to the number of CPU cores Runtime.availableProcessors().
Params:
  • selectorRunnersCount –
Returns:the builder
/** * Sets the number of {@link Selector}s to be created to serve Transport * connections. <tt>-1</tt> is the default value, which lets the Transport * to pick the value, usually it's equal to the number of CPU cores * {@link Runtime#availableProcessors()}. * * @param selectorRunnersCount * @return the builder */
public T setSelectorRunnersCount(final int selectorRunnersCount) { this.selectorRunnerCount = selectorRunnersCount; return getThis(); }
Returns:the ThreadPoolConfig that will be used to construct the ExecutorService for IOStrategies that require worker threads. This method will return null if a ThreadPoolConfig had not been previously set.
/** * @return the {@link ThreadPoolConfig} that will be used to construct the * {@link java.util.concurrent.ExecutorService} for <code>IOStrategies</code> * that require worker threads. This method will return <code>null</code> * if a {@link ThreadPoolConfig} had not been previously set. */
public ThreadPoolConfig getWorkerThreadPoolConfig() { return workerConfig; }
Sets the ThreadPoolConfig that will be used to construct the ExecutorService for IOStrategies that require worker threads
/** * Sets the {@link ThreadPoolConfig} that will be used to construct the * {@link java.util.concurrent.ExecutorService} for <code>IOStrategies</code> * that require worker threads */
public T setWorkerThreadPoolConfig(final ThreadPoolConfig workerConfig) { this.workerConfig = workerConfig; return getThis(); }
Returns:the ThreadPoolConfig that will be used to construct the ExecutorService which will run the NIOTransport's SelectorRunners.
/** * @return the {@link ThreadPoolConfig} that will be used to construct the * {@link java.util.concurrent.ExecutorService} which will run the {@link NIOTransport}'s * {@link org.glassfish.grizzly.nio.SelectorRunner}s. */
public ThreadPoolConfig getSelectorThreadPoolConfig() { return kernelConfig; }
Sets the ThreadPoolConfig that will be used to construct the ExecutorService which will run the NIOTransport's SelectorRunners.
/** * Sets the {@link ThreadPoolConfig} that will be used to construct the * {@link java.util.concurrent.ExecutorService} which will run the {@link NIOTransport}'s * {@link org.glassfish.grizzly.nio.SelectorRunner}s. */
public T setSelectorThreadPoolConfig(final ThreadPoolConfig kernelConfig) { this.kernelConfig = kernelConfig; return getThis(); }
Returns:the IOStrategy that will be used by the created NIOTransport.
/** * @return the {@link IOStrategy} that will be used by the created {@link NIOTransport}. */
public IOStrategy getIOStrategy() { return ioStrategy; }

Changes the IOStrategy that will be used. Invoking this method may change the return value of getWorkerThreadPoolConfig()

Params:
Returns:this NIOTransportBuilder
/** * <p> * Changes the {@link IOStrategy} that will be used. Invoking this method * may change the return value of {@link #getWorkerThreadPoolConfig()} * * @param ioStrategy the {@link IOStrategy} to use. * * @return this <code>NIOTransportBuilder</code> */
public T setIOStrategy(final IOStrategy ioStrategy) { this.ioStrategy = ioStrategy; return getThis(); }
Returns:the MemoryManager that will be used by the created NIOTransport. If not explicitly set, then MemoryManager.DEFAULT_MEMORY_MANAGER will be used.
/** * @return the {@link MemoryManager} that will be used by the created {@link NIOTransport}. * If not explicitly set, then {@link MemoryManager#DEFAULT_MEMORY_MANAGER} will be used. */
public MemoryManager getMemoryManager() { return memoryManager; }
Set the MemoryManager to be used by the created NIOTransport.
Params:
Returns:this NIOTransportBuilder
/** * Set the {@link MemoryManager} to be used by the created {@link NIOTransport}. * * @param memoryManager the {@link MemoryManager}. * * @return this <code>NIOTransportBuilder</code> */
public T setMemoryManager(final MemoryManager memoryManager) { this.memoryManager = memoryManager; return getThis(); }
Returns:the SelectorHandler that will be used by the created NIOTransport. If not explicitly set, then SelectorHandler.DEFAULT_SELECTOR_HANDLER will be used.
/** * @return the {@link SelectorHandler} that will be used by the created {@link NIOTransport}. * If not explicitly set, then {@link SelectorHandler#DEFAULT_SELECTOR_HANDLER} will be used. */
public SelectorHandler getSelectorHandler() { return selectorHandler; }
Set the SelectorHandler to be used by the created NIOTransport.
Params:
Returns:this NIOTransportBuilder
/** * Set the {@link SelectorHandler} to be used by the created {@link NIOTransport}. * * @param selectorHandler the {@link SelectorHandler}. * * @return this <code>NIOTransportBuilder</code> */
public T setSelectorHandler(final SelectorHandler selectorHandler) { this.selectorHandler = selectorHandler; return getThis(); }
Returns:the SelectionKeyHandler that will be used by the created NIOTransport. If not explicitly set, then SelectionKeyHandler.DEFAULT_SELECTION_KEY_HANDLER will be used.
/** * @return the {@link SelectionKeyHandler} that will be used by the created {@link NIOTransport}. * If not explicitly set, then {@link SelectionKeyHandler#DEFAULT_SELECTION_KEY_HANDLER} will be used. */
public SelectionKeyHandler getSelectionKeyHandler() { return selectionKeyHandler; }
Set the SelectionKeyHandler to be used by the created NIOTransport.
Params:
Returns:this NIOTransportBuilder
/** * Set the {@link SelectionKeyHandler} to be used by the created {@link NIOTransport}. * * @param selectionKeyHandler the {@link SelectionKeyHandler}. * * @return this <code>NIOTransportBuilder</code> */
public T setSelectionKeyHandler(final SelectionKeyHandler selectionKeyHandler) { this.selectionKeyHandler = selectionKeyHandler; return getThis(); }
Returns:the AttributeBuilder that will be used by the created NIOTransport. If not explicitly set, then AttributeBuilder.DEFAULT_ATTRIBUTE_BUILDER will be used.
/** * @return the {@link AttributeBuilder} that will be used by the created {@link NIOTransport}. * If not explicitly set, then {@link AttributeBuilder#DEFAULT_ATTRIBUTE_BUILDER} will be used. */
public AttributeBuilder getAttributeBuilder() { return attributeBuilder; }
Set the AttributeBuilder to be used by the created NIOTransport.
Params:
Returns:this NIOTransportBuilder
/** * Set the {@link AttributeBuilder} to be used by the created {@link NIOTransport}. * * @param attributeBuilder the {@link AttributeBuilder}. * * @return this <code>NIOTransportBuilder</code> */
public T setAttributeBuilder(AttributeBuilder attributeBuilder) { this.attributeBuilder = attributeBuilder; return getThis(); }
Returns:the NIOChannelDistributor that will be used by the created NIOTransport. If not explicitly set, then AttributeBuilder.DEFAULT_ATTRIBUTE_BUILDER will be used.
/** * @return the {@link NIOChannelDistributor} that will be used by the created {@link NIOTransport}. * If not explicitly set, then {@link AttributeBuilder#DEFAULT_ATTRIBUTE_BUILDER} will be used. */
public NIOChannelDistributor getNIOChannelDistributor() { return nioChannelDistributor; }
Set the NIOChannelDistributor to be used by the created NIOTransport.
Params:
Returns:this NIOTransportBuilder
/** * Set the {@link NIOChannelDistributor} to be used by the created {@link NIOTransport}. * * @param nioChannelDistributor the {@link NIOChannelDistributor}. * * @return this <code>NIOTransportBuilder</code> */
public T setNIOChannelDistributor(NIOChannelDistributor nioChannelDistributor) { this.nioChannelDistributor = nioChannelDistributor; return getThis(); }
Returns:the SelectorProvider that will be used by the created NIOTransport. If not explicitly set, then SelectorProvider.provider() will be used.
/** * @return the {@link SelectorProvider} that will be used by the created {@link NIOTransport}. * If not explicitly set, then {@link SelectorProvider#provider()} will be used. */
public SelectorProvider getSelectorProvider() { return selectorProvider; }
Set the SelectorProvider to be used by the created NIOTransport.
Params:
Returns:this NIOTransportBuilder
/** * Set the {@link SelectorProvider} to be used by the created {@link NIOTransport}. * * @param selectorProvider the {@link SelectorProvider}. * * @return this <code>NIOTransportBuilder</code> */
public T setSelectorProvider(SelectorProvider selectorProvider) { this.selectorProvider = selectorProvider; return getThis(); }
See Also:
  • getName.getName()
/** * @see Transport#getName() */
public String getName() { return name; }
See Also:
  • setName.setName(String)
Returns:this NIOTransportBuilder
/** * @see Transport#setName(String) * * @return this <code>NIOTransportBuilder</code> */
public T setName(String name) { this.name = name; return getThis(); }
See Also:
  • getProcessor.getProcessor()
/** * @see Transport#getProcessor() */
public Processor getProcessor() { return processor; }
See Also:
  • setProcessor.setProcessor(Processor)
Returns:this NIOTransportBuilder
/** * @see Transport#setProcessor(Processor) * * @return this <code>NIOTransportBuilder</code> */
public T setProcessor(Processor processor) { this.processor = processor; return getThis(); }
See Also:
  • ()
/** * @see Transport#getProcessorSelector() () */
public ProcessorSelector getProcessorSelector() { return processorSelector; }
See Also:
  • setProcessorSelector.setProcessorSelector(ProcessorSelector)
Returns:this NIOTransportBuilder
/** * @see Transport#setProcessorSelector(ProcessorSelector) * * @return this <code>NIOTransportBuilder</code> */
public T setProcessorSelector(ProcessorSelector processorSelector) { this.processorSelector = processorSelector; return getThis(); }
See Also:
  • ()
/** * @see Transport#getReadBufferSize() () */
public int getReadBufferSize() { return readBufferSize; }
See Also:
  • setReadBufferSize.setReadBufferSize(int)
Returns:this NIOTransportBuilder
/** * @see Transport#setReadBufferSize(int) * * @return this <code>NIOTransportBuilder</code> */
public T setReadBufferSize(int readBufferSize) { this.readBufferSize = readBufferSize; return getThis(); }
See Also:
  • getWriteBufferSize.getWriteBufferSize()
/** * @see Transport#getWriteBufferSize() */
public int getWriteBufferSize() { return writeBufferSize; }
See Also:
  • setWriteBufferSize.setWriteBufferSize(int)
Returns:this NIOTransportBuilder
/** * @see Transport#setWriteBufferSize(int) * * @return this <code>NIOTransportBuilder</code> */
public T setWriteBufferSize(int writeBufferSize) { this.writeBufferSize = writeBufferSize; return getThis(); }
See Also:
  • getClientSocketSoTimeout.getClientSocketSoTimeout()
/** * @see NIOTransport#getClientSocketSoTimeout() */
public int getClientSocketSoTimeout() { return clientSocketSoTimeout; }
See Also:
Returns:this NIOTransportBuilder
/** * @return this <code>NIOTransportBuilder</code> * @see NIOTransport#setClientSocketSoTimeout(int) */
public T setClientSocketSoTimeout(int clientSocketSoTimeout) { this.clientSocketSoTimeout = clientSocketSoTimeout; return getThis(); }
See Also:
  • getConnectionTimeout.getConnectionTimeout()
/** * @see NIOTransport#getConnectionTimeout() */
public int getConnectionTimeout() { return connectionTimeout; }
See Also:
Returns:this NIOTransportBuilder
/** * @return this <code>NIOTransportBuilder</code> * @see NIOTransport#setConnectionTimeout(int) */
public T setConnectionTimeout(int connectionTimeout) { this.connectionTimeout = connectionTimeout; return getThis(); }
See Also:
  • getReadTimeout.getReadTimeout(TimeUnit)
/** * @see Transport#getReadTimeout(java.util.concurrent.TimeUnit) */
public long getReadTimeout(final TimeUnit timeUnit) { if (readTimeout <= 0) { return -1; } else { return timeUnit.convert(readTimeout, TimeUnit.MILLISECONDS); } }
See Also:
  • setReadTimeout.setReadTimeout(long, TimeUnit)
/** * @see Transport#setReadTimeout(long, java.util.concurrent.TimeUnit) */
public T setReadTimeout(final long timeout, final TimeUnit timeUnit) { if (timeout <= 0) { readTimeout = -1; } else { readTimeout = TimeUnit.MILLISECONDS.convert(timeout, timeUnit); } return getThis(); }
See Also:
  • getWriteTimeout.getWriteTimeout(TimeUnit)
/** * @see Transport#getWriteTimeout(java.util.concurrent.TimeUnit) */
public long getWriteTimeout(final TimeUnit timeUnit) { if (writeTimeout <= 0) { return -1; } else { return timeUnit.convert(writeTimeout, TimeUnit.MILLISECONDS); } }
See Also:
  • setWriteTimeout.setWriteTimeout(long, TimeUnit)
/** * @see Transport#setWriteTimeout(long, java.util.concurrent.TimeUnit) */
public T setWriteTimeout(final long timeout, final TimeUnit timeUnit) { if (timeout <= 0) { writeTimeout = -1; } else { writeTimeout = TimeUnit.MILLISECONDS.convert(timeout, timeUnit); } return getThis(); }
See Also:
  • isReuseAddress.isReuseAddress()
/** * @see org.glassfish.grizzly.nio.transport.TCPNIOTransport#isReuseAddress() */
public boolean isReuseAddress() { return reuseAddress; }
See Also:
Returns:this TCPNIOTransportBuilder
/** * @return this <code>TCPNIOTransportBuilder</code> * @see org.glassfish.grizzly.nio.transport.TCPNIOTransport#setReuseAddress(boolean) */
public T setReuseAddress(boolean reuseAddress) { this.reuseAddress = reuseAddress; return getThis(); }
See Also:
  • Note: the value is per connection, not transport total.
/** * @see org.glassfish.grizzly.asyncqueue.AsyncQueueWriter#getMaxPendingBytesPerConnection() * <p/> * Note: the value is per connection, not transport total. */
public int getMaxAsyncWriteQueueSizeInBytes() { return maxPendingBytesPerConnection; }
See Also:
Returns:this TCPNIOTransportBuilder
/** * @return this <code>TCPNIOTransportBuilder</code> * @see org.glassfish.grizzly.asyncqueue.AsyncQueueWriter#setMaxPendingBytesPerConnection(int) * <p/> * Note: the value is per connection, not transport total. */
public T setMaxAsyncWriteQueueSizeInBytes(final int maxAsyncWriteQueueSizeInBytes) { this.maxPendingBytesPerConnection = maxAsyncWriteQueueSizeInBytes; return getThis(); }
See Also:
  • isOptimizedForMultiplexing.isOptimizedForMultiplexing()
/** * @see org.glassfish.grizzly.nio.NIOTransport#isOptimizedForMultiplexing() */
public boolean isOptimizedForMultiplexing() { return optimizedForMultiplexing; }
See Also:
  • setOptimizedForMultiplexing.setOptimizedForMultiplexing(boolean)
Returns:this TCPNIOTransportBuilder
/** * @see org.glassfish.grizzly.nio.NIOTransport#setOptimizedForMultiplexing(boolean) * * @return this <code>TCPNIOTransportBuilder</code> */
public T setOptimizedForMultiplexing(final boolean optimizedForMultiplexing) { this.optimizedForMultiplexing = optimizedForMultiplexing; return getThis(); }
Returns:an NIOTransport based on the builder's configuration.
/** * @return an {@link NIOTransport} based on the builder's configuration. */
public NIOTransport build() { NIOTransport transport = create(name); transport.setIOStrategy(ioStrategy); if (workerConfig != null) { transport.setWorkerThreadPoolConfig(workerConfig.copy()); } if (kernelConfig != null) { transport.setKernelThreadPoolConfig(kernelConfig.copy()); } transport.setSelectorProvider(selectorProvider); transport.setSelectorHandler(selectorHandler); transport.setSelectionKeyHandler(selectionKeyHandler); transport.setMemoryManager(memoryManager); transport.setAttributeBuilder(attributeBuilder); transport.setSelectorRunnersCount(selectorRunnerCount); transport.setNIOChannelDistributor(nioChannelDistributor); transport.setProcessor(processor); transport.setProcessorSelector(processorSelector); transport.setClientSocketSoTimeout(clientSocketSoTimeout); transport.setConnectionTimeout(connectionTimeout); transport.setReadTimeout(readTimeout, TimeUnit.MILLISECONDS); transport.setWriteTimeout(writeTimeout, TimeUnit.MILLISECONDS); transport.setReadBufferSize(readBufferSize); transport.setWriteBufferSize(writeBufferSize); transport.setReuseAddress(reuseAddress); transport.setOptimizedForMultiplexing(isOptimizedForMultiplexing()); transport.getAsyncQueueIO() .getWriter() .setMaxPendingBytesPerConnection( maxPendingBytesPerConnection); return transport; } // ------------------------------------------------------- Protected Methods /** * See: <a href="http://www.angelikalanger.com/GenericsFAQ/FAQSections/ProgrammingIdioms.html#FAQ205">http://www.angelikalanger.com/GenericsFAQ/FAQSections/ProgrammingIdioms.html#FAQ205</a> */ protected abstract T getThis(); protected abstract NIOTransport create(String name); }