Example usage for io.netty.channel ChannelOption SO_KEEPALIVE

List of usage examples for io.netty.channel ChannelOption SO_KEEPALIVE

Introduction

In this page you can find the example usage for io.netty.channel ChannelOption SO_KEEPALIVE.

Prototype

ChannelOption SO_KEEPALIVE

To view the source code for io.netty.channel ChannelOption SO_KEEPALIVE.

Click Source Link

Usage

From source file:org.apache.helix.ipc.netty.NettyHelixIPCService.java

License:Apache License

/**
 * Starts message handling server, creates client bootstrap, and bootstraps partition routing
 * table.//from  w  w  w.ja  v  a  2 s.c o  m
 */
public void start() throws Exception {
    if (isShutdown.getAndSet(false)) {
        eventLoopGroup = new NioEventLoopGroup();

        statTxMsg = metricRegistry.meter(MetricRegistry.name(NettyHelixIPCService.class, "txMsg"));
        statRxMsg = metricRegistry.meter(MetricRegistry.name(NettyHelixIPCService.class, "rxMsg"));
        statTxBytes = metricRegistry.meter(MetricRegistry.name(NettyHelixIPCService.class, "txBytes"));
        statRxBytes = metricRegistry.meter(MetricRegistry.name(NettyHelixIPCService.class, "rxBytes"));
        statChannelOpen = metricRegistry
                .counter(MetricRegistry.name(NettyHelixIPCService.class, "channelOpen"));
        statError = metricRegistry.counter(MetricRegistry.name(NettyHelixIPCService.class, "error"));

        // Report metrics via JMX
        jmxReporter = JmxReporter.forRegistry(metricRegistry).build();
        jmxReporter.start();
        LOG.info("Registered JMX metrics reporter");

        new ServerBootstrap().group(eventLoopGroup).channel(NioServerSocketChannel.class)
                .option(ChannelOption.SO_KEEPALIVE, true).childOption(ChannelOption.SO_KEEPALIVE, true)
                .childHandler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        socketChannel.pipeline()
                                .addLast(new LengthFieldBasedFrameDecoder(config.getMaxFrameLength(),
                                        LENGTH_FIELD_OFFSET, LENGTH_FIELD_LENGTH, LENGTH_ADJUSTMENT,
                                        INITIAL_BYTES_TO_STRIP));
                        socketChannel.pipeline().addLast(new NettyHelixIPCCallbackHandler(
                                config.getInstanceName(), callbacks, statRxMsg, statRxBytes));
                    }
                }).bind(new InetSocketAddress(config.getPort()));
        LOG.info("Listening on port " + config.getPort());

        clientBootstrap = new Bootstrap().group(eventLoopGroup).channel(NioSocketChannel.class)
                .option(ChannelOption.SO_KEEPALIVE, true).handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        socketChannel.pipeline().addLast(new LengthFieldPrepender(LENGTH_FIELD_LENGTH, true));
                        socketChannel.pipeline().addLast(new NettyHelixIPCBackPressureHandler());
                    }
                });
    }
}

From source file:org.apache.hive.spark.client.rpc.Rpc.java

License:Apache License

/**
 * Creates an RPC client for a server running on the given remote host and port.
 *
 * @param config RPC configuration data.
 * @param eloop Event loop for managing the connection.
 * @param host Host name or IP address to connect to.
 * @param port Port where server is listening.
 * @param clientId The client ID that identifies the connection.
 * @param secret Secret for authenticating the client with the server.
 * @param dispatcher Dispatcher used to handle RPC calls.
 * @return A future that can be used to monitor the creation of the RPC object.
 *//*from   w w w .j a  v a 2 s. co m*/
public static Promise<Rpc> createClient(Map<String, String> config, final NioEventLoopGroup eloop, String host,
        int port, final String clientId, final String secret, final RpcDispatcher dispatcher) throws Exception {
    final RpcConfiguration rpcConf = new RpcConfiguration(config);
    int connectTimeoutMs = (int) rpcConf.getConnectTimeoutMs();

    final ChannelFuture cf = new Bootstrap().group(eloop).handler(new ChannelInboundHandlerAdapter() {
    }).channel(NioSocketChannel.class).option(ChannelOption.SO_KEEPALIVE, true)
            .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectTimeoutMs).connect(host, port);

    final Promise<Rpc> promise = eloop.next().newPromise();
    final AtomicReference<Rpc> rpc = new AtomicReference<Rpc>();

    // Set up a timeout to undo everything.
    final Runnable timeoutTask = new Runnable() {
        @Override
        public void run() {
            promise.setFailure(new TimeoutException("Timed out waiting for RPC server connection."));
        }
    };
    final ScheduledFuture<?> timeoutFuture = eloop.schedule(timeoutTask, rpcConf.getServerConnectTimeoutMs(),
            TimeUnit.MILLISECONDS);

    // The channel listener instantiates the Rpc instance when the connection is established,
    // and initiates the SASL handshake.
    cf.addListener(new ChannelFutureListener() {
        @Override
        public void operationComplete(ChannelFuture cf) throws Exception {
            if (cf.isSuccess()) {
                SaslClientHandler saslHandler = new SaslClientHandler(rpcConf, clientId, promise, timeoutFuture,
                        secret, dispatcher);
                Rpc rpc = createRpc(rpcConf, saslHandler, (SocketChannel) cf.channel(), eloop);
                saslHandler.rpc = rpc;
                saslHandler.sendHello(cf.channel());
            } else {
                promise.setFailure(cf.cause());
            }
        }
    });

    // Handle cancellation of the promise.
    promise.addListener(new GenericFutureListener<Promise<Rpc>>() {
        @Override
        public void operationComplete(Promise<Rpc> p) {
            if (p.isCancelled()) {
                cf.cancel(true);
            }
        }
    });

    return promise;
}

From source file:org.apache.hive.spark.client.rpc.RpcServer.java

License:Apache License

public RpcServer(Map<String, String> mapConf) throws IOException, InterruptedException {
    this.config = new RpcConfiguration(mapConf);
    this.group = new NioEventLoopGroup(this.config.getRpcThreadCount(),
            new ThreadFactoryBuilder().setNameFormat("RPC-Handler-%d").setDaemon(true).build());
    this.channel = new ServerBootstrap().group(group).channel(NioServerSocketChannel.class)
            .childHandler(new ChannelInitializer<SocketChannel>() {
                @Override/*from  w  ww.j  a v  a 2  s .  c o m*/
                public void initChannel(SocketChannel ch) throws Exception {
                    SaslServerHandler saslHandler = new SaslServerHandler(config);
                    final Rpc newRpc = Rpc.createServer(saslHandler, config, ch, group);
                    saslHandler.rpc = newRpc;

                    Runnable cancelTask = new Runnable() {
                        @Override
                        public void run() {
                            LOG.warn("Timed out waiting for hello from client.");
                            newRpc.close();
                        }
                    };
                    saslHandler.cancelTask = group.schedule(cancelTask,
                            RpcServer.this.config.getServerConnectTimeoutMs(), TimeUnit.MILLISECONDS);

                }
            }).option(ChannelOption.SO_BACKLOG, 1).option(ChannelOption.SO_REUSEADDR, true)
            .childOption(ChannelOption.SO_KEEPALIVE, true).bind(0).sync().channel();
    this.port = ((InetSocketAddress) channel.localAddress()).getPort();
    this.pendingClients = Maps.newConcurrentMap();
    this.address = this.config.getServerAddress();
}

From source file:org.apache.jackrabbit.oak.plugins.segment.standby.client.StandbyClient.java

License:Apache License

public void run() {
    if (!isRunning()) {
        // manually stopped
        return;//from ww  w .  j  av a 2s .  c  om
    }

    Bootstrap b;
    synchronized (this.sync) {
        if (this.active) {
            return;
        }
        state = STATUS_STARTING;
        handler = new StandbyClientHandler(this.store, observer, running, readTimeoutMs, autoClean);
        group = new NioEventLoopGroup();

        b = new Bootstrap();
        b.group(group);
        b.channel(NioSocketChannel.class);
        b.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, readTimeoutMs);
        b.option(ChannelOption.TCP_NODELAY, true);
        b.option(ChannelOption.SO_REUSEADDR, true);
        b.option(ChannelOption.SO_KEEPALIVE, true);

        b.handler(new ChannelInitializer<SocketChannel>() {
            @Override
            public void initChannel(SocketChannel ch) throws Exception {
                ChannelPipeline p = ch.pipeline();
                if (sslContext != null) {
                    p.addLast(sslContext.newHandler(ch.alloc()));
                }
                p.addLast("readTimeoutHandler", new ReadTimeoutHandler(readTimeoutMs, TimeUnit.MILLISECONDS));
                p.addLast(new StringEncoder(CharsetUtil.UTF_8));
                p.addLast(new SnappyFramedDecoder(true));
                p.addLast(new RecordIdDecoder(store));
                p.addLast(handler);
            }
        });
        state = STATUS_RUNNING;
        this.active = true;
    }

    try {
        long startTimestamp = System.currentTimeMillis();
        // Start the client.
        ChannelFuture f = b.connect(host, port).sync();
        // Wait until the connection is closed.
        f.channel().closeFuture().sync();
        this.failedRequests = 0;
        this.syncStartTimestamp = startTimestamp;
        this.syncEndTimestamp = System.currentTimeMillis();
        this.lastSuccessfulRequest = syncEndTimestamp / 1000;
    } catch (Exception e) {
        this.failedRequests++;
        log.error("Failed synchronizing state.", e);
    } finally {
        synchronized (this.sync) {
            this.active = false;
            shutdownNetty();
        }
    }
}

From source file:org.apache.jackrabbit.oak.plugins.segment.standby.server.StandbyServer.java

License:Apache License

public StandbyServer(int port, final SegmentStore store, String[] allowedClientIPRanges, boolean secure)
        throws CertificateException, SSLException {
    this.port = port;

    if (secure) {
        SelfSignedCertificate ssc = new SelfSignedCertificate();
        sslContext = SslContext.newServerContext(ssc.certificate(), ssc.privateKey());
    }/*  ww  w.  j  a va 2  s  .  co m*/

    observer = new CommunicationObserver("primary");
    handler = new StandbyServerHandler(store, observer, allowedClientIPRanges);
    bossGroup = new NioEventLoopGroup(1);
    workerGroup = new NioEventLoopGroup();

    final MBeanServer jmxServer = ManagementFactory.getPlatformMBeanServer();
    try {
        jmxServer.registerMBean(new StandardMBean(this, StandbyStatusMBean.class),
                new ObjectName(this.getMBeanName()));
    } catch (Exception e) {
        log.error("can't register standby status mbean", e);
    }

    b = new ServerBootstrap();
    b.group(bossGroup, workerGroup);
    b.channel(NioServerSocketChannel.class);

    b.option(ChannelOption.TCP_NODELAY, true);
    b.option(ChannelOption.SO_REUSEADDR, true);
    b.childOption(ChannelOption.TCP_NODELAY, true);
    b.childOption(ChannelOption.SO_REUSEADDR, true);
    b.childOption(ChannelOption.SO_KEEPALIVE, true);

    b.childHandler(new ChannelInitializer<SocketChannel>() {
        @Override
        public void initChannel(SocketChannel ch) throws Exception {
            ChannelPipeline p = ch.pipeline();
            if (sslContext != null) {
                p.addLast(sslContext.newHandler(ch.alloc()));
            }
            p.addLast(new LineBasedFrameDecoder(8192));
            p.addLast(new StringDecoder(CharsetUtil.UTF_8));
            p.addLast(new SnappyFramedEncoder());
            p.addLast(new RecordIdEncoder());
            p.addLast(new SegmentEncoder());
            p.addLast(new BlobEncoder());
            p.addLast(handler);
        }
    });
}

From source file:org.apache.qpid.jms.transports.netty.NettyTcpTransport.java

License:Apache License

private void configureNetty(Bootstrap bootstrap, TransportOptions options) {
    bootstrap.option(ChannelOption.TCP_NODELAY, options.isTcpNoDelay());
    bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, options.getConnectTimeout());
    bootstrap.option(ChannelOption.SO_KEEPALIVE, options.isTcpKeepAlive());
    bootstrap.option(ChannelOption.SO_LINGER, options.getSoLinger());
    bootstrap.option(ChannelOption.ALLOCATOR, PartialPooledByteBufAllocator.INSTANCE);

    if (options.getSendBufferSize() != -1) {
        bootstrap.option(ChannelOption.SO_SNDBUF, options.getSendBufferSize());
    }/*from w  ww.j  av a 2s.co  m*/

    if (options.getReceiveBufferSize() != -1) {
        bootstrap.option(ChannelOption.SO_RCVBUF, options.getReceiveBufferSize());
        bootstrap.option(ChannelOption.RCVBUF_ALLOCATOR,
                new FixedRecvByteBufAllocator(options.getReceiveBufferSize()));
    }

    if (options.getTrafficClass() != -1) {
        bootstrap.option(ChannelOption.IP_TOS, options.getTrafficClass());
    }
}

From source file:org.apache.reef.wake.remote.transport.netty.NettyMessagingTransport.java

License:Apache License

/**
 * Constructs a messaging transport/*from w ww.j av  a 2 s .co m*/
 *
 * @param hostAddress   the server host address
 * @param port          the server listening port; when it is 0, randomly assign a port number
 * @param clientStage   the client-side stage that handles transport events
 * @param serverStage   the server-side stage that handles transport events
 * @param numberOfTries the number of tries of connection
 * @param retryTimeout  the timeout of reconnection
 */
public NettyMessagingTransport(final String hostAddress, int port, final EStage<TransportEvent> clientStage,
        final EStage<TransportEvent> serverStage, final int numberOfTries, final int retryTimeout) {

    if (port < 0) {
        throw new RemoteRuntimeException("Invalid server port: " + port);
    }

    this.numberOfTries = numberOfTries;
    this.retryTimeout = retryTimeout;
    this.clientEventListener = new NettyClientEventListener(this.addrToLinkRefMap, clientStage);
    this.serverEventListener = new NettyServerEventListener(this.addrToLinkRefMap, serverStage);

    this.serverBossGroup = new NioEventLoopGroup(SERVER_BOSS_NUM_THREADS,
            new DefaultThreadFactory(CLASS_NAME + "ServerBoss"));
    this.serverWorkerGroup = new NioEventLoopGroup(SERVER_WORKER_NUM_THREADS,
            new DefaultThreadFactory(CLASS_NAME + "ServerWorker"));
    this.clientWorkerGroup = new NioEventLoopGroup(CLIENT_WORKER_NUM_THREADS,
            new DefaultThreadFactory(CLASS_NAME + "ClientWorker"));

    this.clientBootstrap = new Bootstrap();
    this.clientBootstrap.group(this.clientWorkerGroup).channel(NioSocketChannel.class)
            .handler(new NettyChannelInitializer(new NettyDefaultChannelHandlerFactory("client",
                    this.clientChannelGroup, this.clientEventListener)))
            .option(ChannelOption.SO_REUSEADDR, true).option(ChannelOption.SO_KEEPALIVE, true);

    this.serverBootstrap = new ServerBootstrap();
    this.serverBootstrap.group(this.serverBossGroup, this.serverWorkerGroup)
            .channel(NioServerSocketChannel.class)
            .childHandler(new NettyChannelInitializer(new NettyDefaultChannelHandlerFactory("server",
                    this.serverChannelGroup, this.serverEventListener)))
            .option(ChannelOption.SO_BACKLOG, 128).option(ChannelOption.SO_REUSEADDR, true)
            .childOption(ChannelOption.SO_KEEPALIVE, true);

    LOG.log(Level.FINE, "Binding to {0}", port);

    Channel acceptor = null;
    try {
        if (port > 0) {
            acceptor = this.serverBootstrap.bind(new InetSocketAddress(hostAddress, port)).sync().channel();
        } else {
            while (acceptor == null) {
                port = randPort.nextInt(PORT_START) + PORT_RANGE;
                LOG.log(Level.FINEST, "Try port {0}", port);
                try {
                    acceptor = this.serverBootstrap.bind(new InetSocketAddress(hostAddress, port)).sync()
                            .channel();
                } catch (final Exception ex) {
                    if (ex instanceof BindException) {
                        LOG.log(Level.FINEST, "The port {0} is already bound. Try again", port);
                    } else {
                        throw ex;
                    }
                }
            }
        }
    } catch (final Exception ex) {
        final RuntimeException transportException = new TransportRuntimeException(
                "Cannot bind to port " + port);
        LOG.log(Level.SEVERE, "Cannot bind to port " + port, ex);

        this.clientWorkerGroup.shutdownGracefully();
        this.serverBossGroup.shutdownGracefully();
        this.serverWorkerGroup.shutdownGracefully();
        throw transportException;
    }

    this.acceptor = acceptor;
    this.serverPort = port;
    this.localAddress = new InetSocketAddress(hostAddress, this.serverPort);

    LOG.log(Level.FINE, "Starting netty transport socket address: {0}", this.localAddress);
}

From source file:org.apache.rocketmq.remoting.netty.NettyRemotingClient.java

License:Apache License

@Override
public void start() {
    this.defaultEventExecutorGroup = new DefaultEventExecutorGroup(//
            nettyClientConfig.getClientWorkerThreads(), //
            new ThreadFactory() {

                private AtomicInteger threadIndex = new AtomicInteger(0);

                @Override/*ww  w  .ja  v  a  2 s .  co  m*/
                public Thread newThread(Runnable r) {
                    return new Thread(r, "NettyClientWorkerThread_" + this.threadIndex.incrementAndGet());
                }
            });

    Bootstrap handler = this.bootstrap.group(this.eventLoopGroupWorker).channel(NioSocketChannel.class)//
            .option(ChannelOption.TCP_NODELAY, true).option(ChannelOption.SO_KEEPALIVE, false)
            .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, nettyClientConfig.getConnectTimeoutMillis())
            .option(ChannelOption.SO_SNDBUF, nettyClientConfig.getClientSocketSndBufSize())
            .option(ChannelOption.SO_RCVBUF, nettyClientConfig.getClientSocketRcvBufSize())
            .handler(new ChannelInitializer<SocketChannel>() {
                @Override
                public void initChannel(SocketChannel ch) throws Exception {
                    ch.pipeline().addLast(defaultEventExecutorGroup, new NettyEncoder(), new NettyDecoder(),
                            new IdleStateHandler(0, 0, nettyClientConfig.getClientChannelMaxIdleTimeSeconds()),
                            new NettyConnectManageHandler(), new NettyClientHandler());
                }
            });

    this.timer.scheduleAtFixedRate(new TimerTask() {
        @Override
        public void run() {
            try {
                NettyRemotingClient.this.scanResponseTable();
            } catch (Exception e) {
                log.error("scanResponseTable exception", e);
            }
        }
    }, 1000 * 3, 1000);

    if (this.channelEventListener != null) {
        this.nettyEventExecuter.start();
    }
}

From source file:org.apache.rocketmq.remoting.netty.NettyRemotingServer.java

License:Apache License

@Override
public void start() {
    this.defaultEventExecutorGroup = new DefaultEventExecutorGroup(nettyServerConfig.getServerWorkerThreads(),
            new ThreadFactory() {

                private AtomicInteger threadIndex = new AtomicInteger(0);

                @Override//from www.ja va2s .  c  o m
                public Thread newThread(Runnable r) {
                    return new Thread(r, "NettyServerCodecThread_" + this.threadIndex.incrementAndGet());
                }
            });

    ServerBootstrap childHandler = this.serverBootstrap
            .group(this.eventLoopGroupBoss, this.eventLoopGroupSelector).channel(NioServerSocketChannel.class)
            .option(ChannelOption.SO_BACKLOG, 1024).option(ChannelOption.SO_REUSEADDR, true)
            .option(ChannelOption.SO_KEEPALIVE, false).childOption(ChannelOption.TCP_NODELAY, true)
            .option(ChannelOption.SO_SNDBUF, nettyServerConfig.getServerSocketSndBufSize())
            .option(ChannelOption.SO_RCVBUF, nettyServerConfig.getServerSocketRcvBufSize())
            .localAddress(new InetSocketAddress(this.nettyServerConfig.getListenPort()))
            .childHandler(new ChannelInitializer<SocketChannel>() {
                @Override
                public void initChannel(SocketChannel ch) throws Exception {
                    ch.pipeline().addLast(defaultEventExecutorGroup, new NettyEncoder(), new NettyDecoder(),
                            new IdleStateHandler(0, 0, nettyServerConfig.getServerChannelMaxIdleTimeSeconds()),
                            new NettyConnetManageHandler(), new NettyServerHandler());
                }
            });

    if (nettyServerConfig.isServerPooledByteBufAllocatorEnable()) {
        childHandler.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
    }

    try {
        ChannelFuture sync = this.serverBootstrap.bind().sync();
        InetSocketAddress addr = (InetSocketAddress) sync.channel().localAddress();
        this.port = addr.getPort();
    } catch (InterruptedException e1) {
        throw new RuntimeException("this.serverBootstrap.bind().sync() InterruptedException", e1);
    }

    if (this.channelEventListener != null) {
        this.nettyEventExecuter.start();
    }

    this.timer.scheduleAtFixedRate(new TimerTask() {

        @Override
        public void run() {
            try {
                NettyRemotingServer.this.scanResponseTable();
            } catch (Exception e) {
                log.error("scanResponseTable exception", e);
            }
        }
    }, 1000 * 3, 1000);
}

From source file:org.apache.spark.network.client.TransportClientFactory.java

License:Apache License

/** Create a completely new {@link TransportClient} to the remote address. */
private TransportClient createClient(InetSocketAddress address) throws IOException, InterruptedException {
    logger.debug("Creating new connection to {}", address);

    Bootstrap bootstrap = new Bootstrap();
    bootstrap.group(workerGroup).channel(socketChannelClass)
            // Disable Nagle's Algorithm since we don't want packets to wait
            .option(ChannelOption.TCP_NODELAY, true).option(ChannelOption.SO_KEEPALIVE, true)
            .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, conf.connectionTimeoutMs())
            .option(ChannelOption.ALLOCATOR, pooledAllocator);

    if (conf.receiveBuf() > 0) {
        bootstrap.option(ChannelOption.SO_RCVBUF, conf.receiveBuf());
    }// ww  w  .j av a2  s.co m

    if (conf.sendBuf() > 0) {
        bootstrap.option(ChannelOption.SO_SNDBUF, conf.sendBuf());
    }

    final AtomicReference<TransportClient> clientRef = new AtomicReference<>();
    final AtomicReference<Channel> channelRef = new AtomicReference<>();

    bootstrap.handler(new ChannelInitializer<SocketChannel>() {
        @Override
        public void initChannel(SocketChannel ch) {
            TransportChannelHandler clientHandler = context.initializePipeline(ch);
            clientRef.set(clientHandler.getClient());
            channelRef.set(ch);
        }
    });

    // Connect to the remote server
    long preConnect = System.nanoTime();
    ChannelFuture cf = bootstrap.connect(address);
    if (!cf.await(conf.connectionTimeoutMs())) {
        throw new IOException(
                String.format("Connecting to %s timed out (%s ms)", address, conf.connectionTimeoutMs()));
    } else if (cf.cause() != null) {
        throw new IOException(String.format("Failed to connect to %s", address), cf.cause());
    }

    TransportClient client = clientRef.get();
    Channel channel = channelRef.get();
    assert client != null : "Channel future completed successfully with null client";

    // Execute any client bootstraps synchronously before marking the Client as successful.
    long preBootstrap = System.nanoTime();
    logger.debug("Connection to {} successful, running bootstraps...", address);
    try {
        for (TransportClientBootstrap clientBootstrap : clientBootstraps) {
            clientBootstrap.doBootstrap(client, channel);
        }
    } catch (Exception e) { // catch non-RuntimeExceptions too as bootstrap may be written in Scala
        long bootstrapTimeMs = (System.nanoTime() - preBootstrap) / 1000000;
        logger.error("Exception while bootstrapping client after " + bootstrapTimeMs + " ms", e);
        client.close();
        throw Throwables.propagate(e);
    }
    long postBootstrap = System.nanoTime();

    logger.info("Successfully created connection to {} after {} ms ({} ms spent in bootstraps)", address,
            (postBootstrap - preConnect) / 1000000, (postBootstrap - preBootstrap) / 1000000);

    return client;
}