All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.stargate.grpc.impl.GrpcImpl Maven / Gradle / Ivy

There is a newer version: 2.1.0-BETA-19
Show newest version
/*
 * Copyright The Stargate 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 io.stargate.grpc.impl;

import io.grpc.Server;
import io.grpc.internal.GrpcUtil;
import io.grpc.netty.shaded.io.grpc.netty.NettyServerBuilder;
import io.grpc.protobuf.services.ProtoReflectionService;
import io.micrometer.core.instrument.binder.grpc.TaggingMetricCollectingServerInterceptor;
import io.stargate.auth.AuthenticationService;
import io.stargate.core.metrics.api.Metrics;
import io.stargate.db.Persistence;
import io.stargate.grpc.metrics.api.GrpcMetricsTagProvider;
import io.stargate.grpc.service.GrpcService;
import io.stargate.grpc.service.interceptors.NewConnectionInterceptor;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class GrpcImpl {
  private static final Logger logger = LoggerFactory.getLogger(GrpcImpl.class);
  private static final Integer EXECUTOR_SIZE = Integer.getInteger("stargate.grpc.executor_size", 8);
  private static final Boolean REFLECTION_ENABLED =
      Boolean.parseBoolean(System.getProperty("stargate.grpc.reflection_enabled", "true"));
  private static final Integer SHUTDOWN_TIMEOUT_SECONDS =
      Integer.getInteger("stargate.grpc.shutdown_timeout_seconds", 60);

  private final Server server;
  private final ScheduledExecutorService executor;

  public GrpcImpl(
      Persistence persistence,
      Metrics metrics,
      AuthenticationService authenticationService,
      GrpcMetricsTagProvider grpcMetricsTagProvider) {

    String listenAddress = null;

    try {
      listenAddress =
          System.getProperty(
              "stargate.listen_address", InetAddress.getLocalHost().getHostAddress());
    } catch (UnknownHostException e) {
      throw new RuntimeException(e);
    }

    if (!Boolean.getBoolean("stargate.bind_to_listen_address")) listenAddress = "0.0.0.0";

    int port = Integer.getInteger("stargate.grpc.port", 8090);

    executor =
        Executors.newScheduledThreadPool(
            EXECUTOR_SIZE, GrpcUtil.getThreadFactory("grpc-stargate-executor", true));

    NettyServerBuilder builder =
        NettyServerBuilder.forAddress(new InetSocketAddress(listenAddress, port))
            // `Persistence` operations are done asynchronously so there isn't a need for a separate
            // thread pool for handling gRPC callbacks in `GrpcService`.
            .directExecutor()
            .intercept(new NewConnectionInterceptor(persistence, authenticationService))
            .intercept(
                new TaggingMetricCollectingServerInterceptor(
                    metrics.getMeterRegistry(), grpcMetricsTagProvider));

    // optional reflection
    if (REFLECTION_ENABLED) {
      builder.addService(ProtoReflectionService.newInstance());
    }

    server = builder.addService(new GrpcService(persistence, executor)).build();
  }

  public void start() {
    try {
      server.start();
    } catch (IOException e) {
      throw new UncheckedIOException(e);
    }
  }

  public void stop() {
    try {
      server.shutdown();
      // Since we provided our own executor, it's our responsibility to shut it down.
      // Note that we don't handle restarts because GrpcActivator never reuses an existing instance
      // (and that wouldn't work anyway, because Server doesn't support it either).
      executor.shutdown();

      long timeoutMillis = TimeUnit.SECONDS.toMillis(SHUTDOWN_TIMEOUT_SECONDS);
      long start = System.currentTimeMillis();

      if (!server.awaitTermination(timeoutMillis, TimeUnit.MILLISECONDS)
          || !executor.awaitTermination(
              timeoutMillis - (System.currentTimeMillis() - start), TimeUnit.MILLISECONDS)) {
        logger.warn("Timed out while waiting for executor shutdown");
      }
    } catch (InterruptedException e) {
      logger.error("Failed waiting for gRPC shutdown", e);
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy