Search in sources :

Example 1 with InternalInstrumented

use of io.grpc.InternalInstrumented in project grpc-java by grpc.

the class NettyServerTest method multiPortStartStopGet.

@Test
public void multiPortStartStopGet() throws Exception {
    InetSocketAddress addr1 = new InetSocketAddress(0);
    InetSocketAddress addr2 = new InetSocketAddress(0);
    NettyServer ns = new NettyServer(Arrays.asList(addr1, addr2), new ReflectiveChannelFactory<>(NioServerSocketChannel.class), new HashMap<ChannelOption<?>, Object>(), new HashMap<ChannelOption<?>, Object>(), new FixedObjectPool<>(eventLoop), new FixedObjectPool<>(eventLoop), false, ProtocolNegotiators.plaintext(), Collections.<ServerStreamTracer.Factory>emptyList(), TransportTracer.getDefaultFactory(), // ignore
    1, // ignore
    false, // ignore
    1, // ignore
    1, // ignore
    1, // ignore
    1, // ignore
    1, // ignore
    1, // ignore
    1, // ignore
    1, // ignore
    true, // ignore
    0, Attributes.EMPTY, channelz);
    final SettableFuture<Void> shutdownCompleted = SettableFuture.create();
    ns.start(new ServerListener() {

        @Override
        public ServerTransportListener transportCreated(ServerTransport transport) {
            return new NoopServerTransportListener();
        }

        @Override
        public void serverShutdown() {
            shutdownCompleted.set(null);
        }
    });
    // SocketStats won't be available until the event loop task of adding SocketStats created by
    // ns.start() complete. So submit a noop task and await until it's drained.
    eventLoop.submit(new Runnable() {

        @Override
        public void run() {
        }
    }).await(5, TimeUnit.SECONDS);
    assertEquals(2, ns.getListenSocketAddresses().size());
    for (SocketAddress address : ns.getListenSocketAddresses()) {
        assertThat(((InetSocketAddress) address).getPort()).isGreaterThan(0);
    }
    List<InternalInstrumented<SocketStats>> stats = ns.getListenSocketStatsList();
    assertEquals(2, ns.getListenSocketStatsList().size());
    for (InternalInstrumented<SocketStats> listenSocket : stats) {
        assertSame(listenSocket, channelz.getSocket(id(listenSocket)));
        // very basic sanity check of the contents
        SocketStats socketStats = listenSocket.getStats().get();
        assertThat(ns.getListenSocketAddresses()).contains(socketStats.local);
        assertNull(socketStats.remote);
    }
    // Cleanup
    ns.shutdown();
    shutdownCompleted.get();
    // listen socket is removed
    for (InternalInstrumented<SocketStats> listenSocket : stats) {
        assertNull(channelz.getSocket(id(listenSocket)));
    }
}
Also used : NioServerSocketChannel(io.netty.channel.socket.nio.NioServerSocketChannel) ChannelOption(io.netty.channel.ChannelOption) ServerStreamTracer(io.grpc.ServerStreamTracer) ServerTransport(io.grpc.internal.ServerTransport) InetSocketAddress(java.net.InetSocketAddress) SocketStats(io.grpc.InternalChannelz.SocketStats) ServerTransportListener(io.grpc.internal.ServerTransportListener) InternalInstrumented(io.grpc.InternalInstrumented) SocketAddress(java.net.SocketAddress) InetSocketAddress(java.net.InetSocketAddress) ServerListener(io.grpc.internal.ServerListener) Test(org.junit.Test)

Example 2 with InternalInstrumented

use of io.grpc.InternalInstrumented in project grpc-java by grpc.

the class NettyServer method start.

@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<ChannelOption<?>, ?> entry : channelOptions.entrySet()) {
            @SuppressWarnings("unchecked") ChannelOption<Object> key = (ChannelOption<Object>) entry.getKey();
            b.option(key, entry.getValue());
        }
    }
    if (childChannelOptions != null) {
        for (Map.Entry<ChannelOption<?>, ?> entry : childChannelOptions.entrySet()) {
            @SuppressWarnings("unchecked") ChannelOption<Object> key = (ChannelOption<Object>) entry.getKey();
            b.childOption(key, entry.getValue());
        }
    }
    b.childHandler(new ChannelInitializer<Channel>() {

        @Override
        public void initChannel(Channel ch) {
            ChannelPromise channelDone = ch.newPromise();
            long maxConnectionAgeInNanos = NettyServer.this.maxConnectionAgeInNanos;
            if (maxConnectionAgeInNanos != MAX_CONNECTION_AGE_NANOS_DISABLED) {
                // apply a random jitter of +/-10% to max connection age
                maxConnectionAgeInNanos = (long) ((.9D + Math.random() * .2D) * maxConnectionAgeInNanos);
            }
            NettyServerTransport transport = new NettyServerTransport(ch, channelDone, protocolNegotiator, streamTracerFactories, transportTracerFactory.create(), maxStreamsPerConnection, autoFlowControl, flowControlWindow, maxMessageSize, maxHeaderListSize, keepAliveTimeInNanos, keepAliveTimeoutInNanos, maxConnectionIdleInNanos, maxConnectionAgeInNanos, maxConnectionAgeGraceInNanos, permitKeepAliveWithoutCalls, permitKeepAliveTimeInNanos, eagAttributes);
            ServerTransportListener transportListener;
            // This is to order callbacks on the listener, not to guard access to channel.
            synchronized (NettyServer.this) {
                if (terminated) {
                    // Server already terminated.
                    ch.close();
                    return;
                }
                // `channel` shutdown can race with `ch` initialization, so this is only safe to increment
                // inside the lock.
                sharedResourceReferenceCounter.retain();
                transportListener = listener.transportCreated(transport);
            }
            /**
             * Releases the event loop if the channel is "done", possibly due to the channel closing.
             */
            final class LoopReleaser implements ChannelFutureListener {

                private boolean done;

                @Override
                public void operationComplete(ChannelFuture future) throws Exception {
                    if (!done) {
                        done = true;
                        sharedResourceReferenceCounter.release();
                    }
                }
            }
            transport.start(transportListener);
            ChannelFutureListener loopReleaser = new LoopReleaser();
            channelDone.addListener(loopReleaser);
            ch.closeFuture().addListener(loopReleaser);
        }
    });
    Future<Map<ChannelFuture, SocketAddress>> bindCallFuture = bossExecutor.submit(new Callable<Map<ChannelFuture, SocketAddress>>() {

        @Override
        public Map<ChannelFuture, SocketAddress> call() {
            Map<ChannelFuture, SocketAddress> bindFutures = new HashMap<>();
            for (SocketAddress address : addresses) {
                ChannelFuture future = b.bind(address);
                channelGroup.add(future.channel());
                bindFutures.put(future, address);
            }
            return bindFutures;
        }
    });
    Map<ChannelFuture, SocketAddress> channelFutures = bindCallFuture.awaitUninterruptibly().getNow();
    if (!bindCallFuture.isSuccess()) {
        channelGroup.close().awaitUninterruptibly();
        throw new IOException(String.format("Failed to bind to addresses %s", addresses), bindCallFuture.cause());
    }
    final List<InternalInstrumented<SocketStats>> socketStats = new ArrayList<>();
    for (Map.Entry<ChannelFuture, SocketAddress> entry : channelFutures.entrySet()) {
        // We'd love to observe interruption, but if interrupted we will need to close the channel,
        // which itself would need an await() to guarantee the port is not used when the method
        // returns. See #6850
        final ChannelFuture future = entry.getKey();
        if (!future.awaitUninterruptibly().isSuccess()) {
            channelGroup.close().awaitUninterruptibly();
            throw new IOException(String.format("Failed to bind to address %s", entry.getValue()), future.cause());
        }
        final InternalInstrumented<SocketStats> listenSocketStats = new ListenSocket(future.channel());
        channelz.addListenSocket(listenSocketStats);
        socketStats.add(listenSocketStats);
        future.channel().closeFuture().addListener(new ChannelFutureListener() {

            @Override
            public void operationComplete(ChannelFuture future) throws Exception {
                channelz.removeListenSocket(listenSocketStats);
            }
        });
    }
    listenSocketStatsList = Collections.unmodifiableList(socketStats);
}
Also used : ChannelOption(io.netty.channel.ChannelOption) ArrayList(java.util.ArrayList) ChannelPromise(io.netty.channel.ChannelPromise) SocketAddress(java.net.SocketAddress) ChannelFuture(io.netty.channel.ChannelFuture) ServerChannel(io.netty.channel.ServerChannel) Channel(io.netty.channel.Channel) IOException(java.io.IOException) ChannelFutureListener(io.netty.channel.ChannelFutureListener) ServerBootstrap(io.netty.bootstrap.ServerBootstrap) IOException(java.io.IOException) SocketStats(io.grpc.InternalChannelz.SocketStats) ServerTransportListener(io.grpc.internal.ServerTransportListener) InternalInstrumented(io.grpc.InternalInstrumented) Map(java.util.Map) HashMap(java.util.HashMap)

Aggregations

SocketStats (io.grpc.InternalChannelz.SocketStats)2 InternalInstrumented (io.grpc.InternalInstrumented)2 ServerTransportListener (io.grpc.internal.ServerTransportListener)2 ChannelOption (io.netty.channel.ChannelOption)2 SocketAddress (java.net.SocketAddress)2 ServerStreamTracer (io.grpc.ServerStreamTracer)1 ServerListener (io.grpc.internal.ServerListener)1 ServerTransport (io.grpc.internal.ServerTransport)1 ServerBootstrap (io.netty.bootstrap.ServerBootstrap)1 Channel (io.netty.channel.Channel)1 ChannelFuture (io.netty.channel.ChannelFuture)1 ChannelFutureListener (io.netty.channel.ChannelFutureListener)1 ChannelPromise (io.netty.channel.ChannelPromise)1 ServerChannel (io.netty.channel.ServerChannel)1 NioServerSocketChannel (io.netty.channel.socket.nio.NioServerSocketChannel)1 IOException (java.io.IOException)1 InetSocketAddress (java.net.InetSocketAddress)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1