com.dimajix.shaded.grpc.netty.NettyServer Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2014 The gRPC Authors
*
* 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.dimajix.shaded.grpc.netty;
import static com.dimajix.shaded.guava.base.Preconditions.checkNotNull;
import static com.dimajix.shaded.grpc.netty.NettyServerBuilder.MAX_CONNECTION_AGE_NANOS_DISABLED;
import static io.netty.channel.ChannelOption.ALLOCATOR;
import static io.netty.channel.ChannelOption.SO_KEEPALIVE;
import com.dimajix.shaded.guava.base.MoreObjects;
import com.dimajix.shaded.guava.base.Preconditions;
import com.dimajix.shaded.guava.util.concurrent.ListenableFuture;
import com.dimajix.shaded.guava.util.concurrent.SettableFuture;
import com.dimajix.shaded.grpc.Attributes;
import com.dimajix.shaded.grpc.InternalChannelz;
import com.dimajix.shaded.grpc.InternalChannelz.SocketStats;
import com.dimajix.shaded.grpc.InternalInstrumented;
import com.dimajix.shaded.grpc.InternalLogId;
import com.dimajix.shaded.grpc.InternalWithLogId;
import com.dimajix.shaded.grpc.ServerStreamTracer;
import com.dimajix.shaded.grpc.internal.InternalServer;
import com.dimajix.shaded.grpc.internal.ObjectPool;
import com.dimajix.shaded.grpc.internal.ServerListener;
import com.dimajix.shaded.grpc.internal.ServerTransportListener;
import com.dimajix.shaded.grpc.internal.TransportTracer;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFactory;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPromise;
import io.netty.channel.EventLoop;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.ServerChannel;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.ChannelGroupFuture;
import io.netty.channel.group.ChannelGroupFutureListener;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.AbstractReferenceCounted;
import io.netty.util.ReferenceCounted;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import java.io.IOException;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Netty-based server implementation.
*/
class NettyServer implements InternalServer, InternalWithLogId {
private static final Logger log = Logger.getLogger(InternalServer.class.getName());
private final InternalLogId logId;
private final List extends SocketAddress> addresses;
private final ChannelFactory extends ServerChannel> channelFactory;
private final Map, ?> channelOptions;
private final Map, ?> childChannelOptions;
private final ProtocolNegotiator protocolNegotiator;
private final int maxStreamsPerConnection;
private final ObjectPool extends EventLoopGroup> bossGroupPool;
private final ObjectPool extends EventLoopGroup> workerGroupPool;
private final boolean forceHeapBuffer;
private EventLoopGroup bossGroup;
private EventLoopGroup workerGroup;
private ServerListener listener;
private final ChannelGroup channelGroup;
private final boolean autoFlowControl;
private final int flowControlWindow;
private final int maxMessageSize;
private final int maxHeaderListSize;
private final long keepAliveTimeInNanos;
private final long keepAliveTimeoutInNanos;
private final long maxConnectionIdleInNanos;
private final long maxConnectionAgeInNanos;
private final long maxConnectionAgeGraceInNanos;
private final boolean permitKeepAliveWithoutCalls;
private final long permitKeepAliveTimeInNanos;
private final Attributes eagAttributes;
private final ReferenceCounted sharedResourceReferenceCounter =
new SharedResourceReferenceCounter();
private final List extends ServerStreamTracer.Factory> streamTracerFactories;
private final TransportTracer.Factory transportTracerFactory;
private final InternalChannelz channelz;
private volatile List> listenSocketStatsList =
Collections.emptyList();
private volatile boolean terminated;
private final EventLoop bossExecutor;
NettyServer(
List extends SocketAddress> addresses,
ChannelFactory extends ServerChannel> channelFactory,
Map, ?> channelOptions,
Map, ?> childChannelOptions,
ObjectPool extends EventLoopGroup> bossGroupPool,
ObjectPool extends EventLoopGroup> workerGroupPool,
boolean forceHeapBuffer,
ProtocolNegotiator protocolNegotiator,
List extends ServerStreamTracer.Factory> streamTracerFactories,
TransportTracer.Factory transportTracerFactory,
int maxStreamsPerConnection, boolean autoFlowControl, int flowControlWindow,
int maxMessageSize, int maxHeaderListSize,
long keepAliveTimeInNanos, long keepAliveTimeoutInNanos,
long maxConnectionIdleInNanos,
long maxConnectionAgeInNanos, long maxConnectionAgeGraceInNanos,
boolean permitKeepAliveWithoutCalls, long permitKeepAliveTimeInNanos,
Attributes eagAttributes, InternalChannelz channelz) {
this.addresses = checkNotNull(addresses, "addresses");
this.channelFactory = checkNotNull(channelFactory, "channelFactory");
checkNotNull(channelOptions, "channelOptions");
this.channelOptions = new HashMap, Object>(channelOptions);
checkNotNull(childChannelOptions, "childChannelOptions");
this.childChannelOptions = new HashMap, Object>(childChannelOptions);
this.bossGroupPool = checkNotNull(bossGroupPool, "bossGroupPool");
this.workerGroupPool = checkNotNull(workerGroupPool, "workerGroupPool");
this.forceHeapBuffer = forceHeapBuffer;
this.bossGroup = bossGroupPool.getObject();
this.bossExecutor = bossGroup.next();
this.channelGroup = new DefaultChannelGroup(this.bossExecutor);
this.workerGroup = workerGroupPool.getObject();
this.protocolNegotiator = checkNotNull(protocolNegotiator, "protocolNegotiator");
this.streamTracerFactories = checkNotNull(streamTracerFactories, "streamTracerFactories");
this.transportTracerFactory = transportTracerFactory;
this.maxStreamsPerConnection = maxStreamsPerConnection;
this.autoFlowControl = autoFlowControl;
this.flowControlWindow = flowControlWindow;
this.maxMessageSize = maxMessageSize;
this.maxHeaderListSize = maxHeaderListSize;
this.keepAliveTimeInNanos = keepAliveTimeInNanos;
this.keepAliveTimeoutInNanos = keepAliveTimeoutInNanos;
this.maxConnectionIdleInNanos = maxConnectionIdleInNanos;
this.maxConnectionAgeInNanos = maxConnectionAgeInNanos;
this.maxConnectionAgeGraceInNanos = maxConnectionAgeGraceInNanos;
this.permitKeepAliveWithoutCalls = permitKeepAliveWithoutCalls;
this.permitKeepAliveTimeInNanos = permitKeepAliveTimeInNanos;
this.eagAttributes = checkNotNull(eagAttributes, "eagAttributes");
this.channelz = Preconditions.checkNotNull(channelz);
this.logId = InternalLogId.allocate(getClass(), addresses.isEmpty() ? "No address" :
String.valueOf(addresses));
}
@Override
public SocketAddress getListenSocketAddress() {
Iterator it = channelGroup.iterator();
if (it.hasNext()) {
return it.next().localAddress();
} else {
// server is not listening/bound yet, just return the original port.
return addresses.isEmpty() ? null : addresses.get(0);
}
}
@Override
public List getListenSocketAddresses() {
List listenSocketAddresses = new ArrayList<>();
for (Channel c: channelGroup) {
listenSocketAddresses.add(c.localAddress());
}
// server is not listening/bound yet, just return the original ports.
if (listenSocketAddresses.isEmpty()) {
listenSocketAddresses.addAll(addresses);
}
return listenSocketAddresses;
}
@Override
public InternalInstrumented getListenSocketStats() {
List> savedListenSocketStatsList = listenSocketStatsList;
return savedListenSocketStatsList.isEmpty() ? null : savedListenSocketStatsList.get(0);
}
@Override
public List> getListenSocketStatsList() {
return listenSocketStatsList;
}
@Override
public void start(ServerListener serverListener) throws IOException {
listener = checkNotNull(serverListener, "serverListener");
final ServerBootstrap b = new ServerBootstrap();
b.option(ALLOCATOR, Utils.getByteBufAllocator(forceHeapBuffer));
b.childOption(ALLOCATOR, Utils.getByteBufAllocator(forceHeapBuffer));
b.group(bossExecutor, workerGroup);
b.channelFactory(channelFactory);
// For non-socket based channel, the option will be ignored.
b.childOption(SO_KEEPALIVE, true);
if (channelOptions != null) {
for (Map.Entry, ?> entry : channelOptions.entrySet()) {
@SuppressWarnings("unchecked")
ChannelOption
© 2015 - 2025 Weber Informatics LLC | Privacy Policy