@Override
    @PreDestroy
    public synchronized void close() {
        if (this.shutdown) {
            return;
        }
        this.shutdown = true;
        final List<ShutdownRecord> shutdownEntries = new ArrayList<>();
        for (final Entry<String, ManagedChannel> entry : this.channels.entrySet()) {
            final ManagedChannel channel = entry.getValue();
            channel.shutdown();
            final long gracePeriod = this.properties.getChannel(entry.getKey()).getShutdownGracePeriod().toMillis();
            shutdownEntries.add(new ShutdownRecord(entry.getKey(), channel, gracePeriod));
        }
        try {
            final long start = System.currentTimeMillis();
            shutdownEntries.sort(comparingLong(ShutdownRecord::getGracePeriod));

            for (final ShutdownRecord entry : shutdownEntries) {
                if (!entry.channel.isTerminated()) {
                    log.debug("Awaiting channel termination: {}", entry.name);

                    final long waitedTime = System.currentTimeMillis() - start;
                    final long waitTime = entry.gracePeriod - waitedTime;

                    if (waitTime > 0) {
                        entry.channel.awaitTermination(waitTime, MILLISECONDS);
                    }
                    entry.channel.shutdownNow();
                }
                log.debug("Completed channel termination: {}", entry.name);
            }
        } catch (final InterruptedException e) {
            Thread.currentThread().interrupt();
            log.debug("We got interrupted - Speeding up shutdown process");
        } finally {
            for (final ManagedChannel channel : this.channels.values()) {
                if (!channel.isTerminated()) {
                    log.debug("Channel not terminated yet - force shutdown now: {} ", channel);
                    channel.shutdownNow();
                }
            }
        }
        final int channelCount = this.channels.size();
        this.channels.clear();
        this.channelStates.clear();
        log.debug("GrpcChannelFactory closed (including {} channels)", channelCount);
    }
Closes this channel factory and the channels created by this instance. The shutdown happens in two phases, first
an orderly shutdown is initiated on all channels and then the method waits for all channels to terminate. If the
channels don't have terminated after 60 seconds then they will be forcefully shutdown.
grpc-client-spring-boot-starter/src/main/java/net/devh/boot/grpc/client/channelfactory/AbstractChannelFactory.java