package org.robobninjas.riemann.guice;
import com.google.common.base.Supplier;
import com.google.common.collect.Queues;
import com.google.inject.*;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.socket.nio.NioClientBossPool;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.jboss.netty.channel.socket.nio.NioWorkerPool;
import org.robotninjas.riemann.client.ClientPipelineFactory;
import org.robotninjas.riemann.client.ReturnableMessage;
import org.robotninjas.riemann.client.RiemannTcpClient;
import org.robotninjas.riemann.pool.RiemannConnectionPool;
import java.net.InetSocketAddress;
import java.util.Queue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class RiemannClientModule extends PrivateModule {
private static final GenericObjectPool.Config DEFAULT_CONFIG = new GenericObjectPool.Config();
private static final int DEFAULT_WORKERS = 1;
static {
DEFAULT_CONFIG.maxActive = 1;
}
private final String address;
private final int port;
private final int numWorkers;
private final GenericObjectPool.Config poolConfig;
public RiemannClientModule(String address, int port, int numWorkers, GenericObjectPool.Config poolConfig) {
this.address = address;
this.port = port;
this.numWorkers = numWorkers;
this.poolConfig = poolConfig;
}
public RiemannClientModule(String address, int port) {
this(address, port, DEFAULT_WORKERS, DEFAULT_CONFIG);
}
@Override
protected void configure() {
bind(RiemannTcpClient.class);
expose(RiemannTcpClient.class);
bind(ClientPipelineFactory.class);
bindSendBufferQueue(Key.get(new TypeLiteral<Queue<MessageEvent>>() {
}));
bindOutstandingMessagesQueue(Key.get(new TypeLiteral<BlockingQueue<ReturnableMessage>>() {
}));
}
@Provides
@Exposed
@Singleton
public RiemannConnectionPool getConnectionPool(RiemannTcpClient client) {
final RiemannConnectionPool pool = new RiemannConnectionPool(client, poolConfig);
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
try {
pool.close();
} catch (Exception e) {
e.printStackTrace();
}
}
});
return pool;
}
@Provides
@Singleton
@NettyExecutor
public Executor getExecutor() {
final ExecutorService executor = Executors.newCachedThreadPool();
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
executor.shutdown();
}
});
return executor;
}
@Provides
@Singleton
public NioClientBossPool getBossPool(@NettyExecutor Executor executor) {
final NioClientBossPool bossPool = new NioClientBossPool(executor, 1);
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
bossPool.shutdown();
}
});
return bossPool;
}
@Provides
@Singleton
public NioWorkerPool getWorkerPool(@NettyExecutor Executor executor) {
final NioWorkerPool workerPool = new NioWorkerPool(executor, numWorkers);
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
workerPool.shutdown();
}
});
return workerPool;
}
@Provides
public ClientBootstrap getClientBootstrap(NioClientBossPool boss, NioWorkerPool worker, ClientPipelineFactory pipelineFactory) {
final NioClientSocketChannelFactory channelFactory = new NioClientSocketChannelFactory(boss, worker);
final ClientBootstrap bootstrap = new ClientBootstrap(channelFactory);
bootstrap.setPipelineFactory(pipelineFactory);
bootstrap.setOption("remoteAddress", new InetSocketAddress(address, port));
bootstrap.setOption("tcpNoDelay", true);
bootstrap.setOption("child.tcpNoDelay", true);
configureBootstrap(bootstrap);
return bootstrap;
}
@Provides
public Supplier<BlockingQueue<ReturnableMessage>> getPromiseQueueSupplier(final Provider<BlockingQueue<ReturnableMessage>> provider) {
return new Supplier<BlockingQueue<ReturnableMessage>>() {
@Override
public BlockingQueue<ReturnableMessage> get() {
return provider.get();
}
};
}
@Provides
public Supplier<Queue<MessageEvent>> getSendBufferQueueSupplier(final Provider<Queue<MessageEvent>> provider) {
return new Supplier<Queue<MessageEvent>>() {
@Override
public Queue<MessageEvent> get() {
return provider.get();
}
};
}
protected void bindOutstandingMessagesQueue(Key<BlockingQueue<ReturnableMessage>> key) {
bind(key).toProvider(new Provider<BlockingQueue<ReturnableMessage>>() {
@Override
public BlockingQueue<ReturnableMessage> get() {
return Queues.newArrayBlockingQueue(10000);
}
});
}
protected void bindSendBufferQueue(Key<Queue<MessageEvent>> key) {
bind(key).toProvider(new Provider<Queue<MessageEvent>>() {
@Override
public Queue<MessageEvent> get() {
return Queues.newConcurrentLinkedQueue();
}
});
}
protected void configureBootstrap(ClientBootstrap bootstrap) {
}
}