/*
* 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 Selector
s 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 Selector
s 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 SelectorRunner
s.
/**
* @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 SelectorRunner
s. /**
* 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: - ioStrategy – the
IOStrategy
to use.
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: - memoryManager – the
MemoryManager
.
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: - selectorHandler – the
SelectorHandler
.
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: - selectionKeyHandler – the
SelectionKeyHandler
.
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: - attributeBuilder – the
AttributeBuilder
.
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: - nioChannelDistributor – the
NIOChannelDistributor
.
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: - selectorProvider – the
SelectorProvider
.
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);
}