/* * Copyright 2016-2016 the original author or 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 org.springframework.boot.autoconfigure.grpc.server; import io.grpc.BindableService; import io.grpc.Server; import io.grpc.ServiceDescriptor; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.context.SmartLifecycle; import java.io.IOException; import java.util.concurrent.atomic.AtomicInteger; /** * Manages the lifecycle of a gRPC server. It uses the {@link GrpcServerFactory} * to create a new instance of a gRPC server, and then manages it according to the * {@link SmartLifecycle}. * @author Ray Tsang */ public class GrpcServerLifecycle implements SmartLifecycle { private static final Log logger = LogFactory .getLog(GrpcServerLifecycle.class); private static AtomicInteger serverCounter = new AtomicInteger(-1); private volatile Server server; private volatile int phase = Integer.MAX_VALUE; private final GrpcServerFactory factory; public GrpcServerLifecycle(GrpcServerFactory factory) { this.factory = factory; } @Override public void start() { try { createAndStartGrpcServer(); } catch (IOException e) { throw new IllegalStateException(e); } } @Override public void stop() { stopAndReleaseGrpcServer(); } @Override public boolean isRunning() { return this.server == null ? false : !this.server.isShutdown(); } @Override public int getPhase() { return this.phase; } @Override public boolean isAutoStartup() { return true; } @Override public void stop(Runnable callback) { this.stop(); callback.run(); } protected void createAndStartGrpcServer() throws IOException { Server localServer = this.server; if (localServer == null) { this.server = factory.createServer(); this.server.start(); logger.info("gRPC Server started, listening on port: " + this.factory.getPort()); Thread awaitThread = new Thread( "container-" + (serverCounter.incrementAndGet())) { @Override public void run() { try { GrpcServerLifecycle.this.server.awaitTermination(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } }; awaitThread.setDaemon(false); awaitThread.start(); } } protected void stopAndReleaseGrpcServer() { Server localServer = this.server; if (localServer != null) { localServer.shutdown(); this.server = null; logger.info("gRPC server stopped"); } } }