/* * Copyright (C) 2012-2016 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.facebook.nifty.client; import com.facebook.nifty.core.NettyConfigBuilderBase; import com.facebook.nifty.core.NiftyTimer; import com.facebook.nifty.ssl.SslClientConfiguration; import com.google.common.base.Strings; import com.google.common.net.HostAndPort; import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.google.inject.Inject; import org.jboss.netty.channel.socket.nio.NioSocketChannelConfig; import org.jboss.netty.util.Timer; import java.lang.reflect.Proxy; import java.util.concurrent.ExecutorService; import java.util.concurrent.ThreadFactory; import static java.util.concurrent.Executors.newCachedThreadPool; /* * Hooks for configuring various parts of Netty. */ public class NettyClientConfigBuilder extends NettyConfigBuilderBase<NettyClientConfigBuilder> { private HostAndPort defaultSocksProxyAddress = null; private SslClientConfiguration sslClientConfiguration; private final NioSocketChannelConfig socketChannelConfig = (NioSocketChannelConfig) Proxy.newProxyInstance( getClass().getClassLoader(), new Class<?>[]{NioSocketChannelConfig.class}, new Magic("") ); @Inject public NettyClientConfigBuilder() { // Thrift turns TCP_NODELAY by default, and turning it off can have latency implications // so let's turn it on by default as well. It can still be switched off by explicitly // calling setTcpNodelay(false) after construction. getSocketChannelConfig().setTcpNoDelay(true); } /** * Returns an implementation of {@link NioSocketChannelConfig} which will be applied to all * {@link org.jboss.netty.channel.socket.nio.NioSocketChannel} instances created for client * connections. * * @return A mutable {@link NioSocketChannelConfig} */ public NioSocketChannelConfig getSocketChannelConfig() { return socketChannelConfig; } /** * A default SOCKS proxy address for client connections. Defaults to {@code null} if not * supplied. * * @param defaultSocksProxyAddress The address of the SOCKS proxy server * @return This builder */ public NettyClientConfigBuilder setDefaultSocksProxyAddress(HostAndPort defaultSocksProxyAddress) { this.defaultSocksProxyAddress = defaultSocksProxyAddress; return this; } public NettyClientConfigBuilder setSSLClientConfiguration(SslClientConfiguration sslClientConfiguration) { this.sslClientConfiguration = sslClientConfiguration; return this; } public NettyClientConfig build() { Timer timer = getTimer(); ExecutorService bossExecutor = getBossExecutor(); int bossThreadCount = getBossThreadCount(); ExecutorService workerExecutor = getWorkerExecutor(); int workerThreadCount = getWorkerThreadCount(); return new NettyClientConfig( getBootstrapOptions(), defaultSocksProxyAddress, timer != null ? timer : new NiftyTimer(threadNamePattern("")), bossExecutor != null ? bossExecutor : buildDefaultBossExecutor(), bossThreadCount, workerExecutor != null ? workerExecutor : buildDefaultWorkerExecutor(), workerThreadCount, sslClientConfiguration ); } private ExecutorService buildDefaultBossExecutor() { return newCachedThreadPool(renamingDaemonThreadFactory(threadNamePattern("-boss-%s"))); } private ExecutorService buildDefaultWorkerExecutor() { return newCachedThreadPool(renamingDaemonThreadFactory(threadNamePattern("-worker-%s"))); } private String threadNamePattern(String suffix) { String niftyName = getNiftyName(); return "nifty-client" + (Strings.isNullOrEmpty(niftyName) ? "" : "-" + niftyName) + suffix; } private ThreadFactory renamingDaemonThreadFactory(String nameFormat) { return new ThreadFactoryBuilder().setNameFormat(nameFormat).setDaemon(true).build(); } }