com.turbospaces.grpc.GrpcChannel Maven / Gradle / Ivy
package com.turbospaces.grpc;
import java.util.Objects;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.context.SmartLifecycle;
import com.turbospaces.boot.AbstractBootstrapAware;
import com.turbospaces.cfg.ApplicationProperties;
import io.grpc.Server;
import io.grpc.netty.NettyServerBuilder;
import io.micrometer.core.instrument.binder.grpc.MetricCollectingServerInterceptor;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.vavr.CheckedConsumer;
public class GrpcChannel extends AbstractBootstrapAware implements SmartLifecycle, CheckedConsumer {
private final int port;
private boolean running;
private Server server;
protected GrpcChannel(int port) {
this.port = port;
}
@Override
public void start() {
try {
NettyServerBuilder forPort = NettyServerBuilder.forPort(port);
accept(forPort);
this.server = forPort.build().start();
this.running = true;
logger.info("grpc server is up and running on={} port", port);
} catch (Exception err) {
throw new BeanInitializationException(err.getMessage(), err);
}
}
@Override
public void stop() {
if (Objects.nonNull(server)) {
server.shutdown();
}
this.running = false;
}
@Override
public boolean isRunning() {
return this.running;
}
@Override
public void accept(NettyServerBuilder builder) {
ApplicationProperties props = bootstrap.props();
builder
.channelType(NioServerSocketChannel.class)
.bossEventLoopGroup(new NioEventLoopGroup(props.NETTY_ACCEPTOR_POOL_SIZE.get()))
.workerEventLoopGroup(new NioEventLoopGroup(props.NETTY_WORKER_POOL_SIZE.get()))
.directExecutor() // ~ application to handle it properly by default (serve in parallel)
.withOption(ChannelOption.SO_BACKLOG, props.TCP_SOCKET_BACKLOG.get())
.withOption(ChannelOption.SO_REUSEADDR, bootstrap.isDevMode())
.withChildOption(ChannelOption.SO_KEEPALIVE, props.TCP_KEEP_ALIVE.get())
.withChildOption(ChannelOption.TCP_NODELAY, props.TCP_NO_DELAY.get())
.intercept(new MetricCollectingServerInterceptor(bootstrap.meterRegistry()));
}
}