docs: @Override
      @PreDestroy
      public synchronized void close() {
          if (this.shutdown) {
              return;
          }
          this.shutdown = true;
          for (final ManagedChannel channel : this.channels.values()) {
              channel.shutdown();
          }
          try {
              final long waitLimit = System.currentTimeMillis() + 60_000; // wait 60 seconds at max
              for (final ManagedChannel channel : this.channels.values()) {
                  int i = 0;
                  do {
                      log.debug("Awaiting channel shutdown: {} ({}s)", channel, i++);
                  } while (System.currentTimeMillis() < waitLimit && !channel.awaitTermination(1, TimeUnit.SECONDS));
              }
          } 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();
          log.debug("GrpcCannelFactory closed (including {} channels)", channelCount);
      }