void start() {
      heartbeatExecutor.scheduleAtFixedRate(() -> {
        IMetaStoreClient msc = null;
        try {
          LOG.debug("Heartbeating compaction transaction id {} for table: {}", txnId, tableName);
          // Create a metastore client for each thread since it is not thread safe
          msc = clientPool.borrowObject();
          msc.heartbeat(txnId, lockId);
        } catch (NoSuchElementException e) {
          LOG.error("Compaction transaction heartbeater pool exhausted, unable to heartbeat", e);
          // This heartbeat attempt failed, and there is no client to return to the pool.
          return;
        } catch (TException e) {
          LOG.error("Error while heartbeating compaction transaction id {} for table: {}", txnId, tableName, e);
          // Heartbeat failed, but the client is not broken, we can return it to the pool.
        } catch (Exception e) {
          LOG.error("Error while heartbeating compaction transaction id {} for table: {}", txnId, tableName, e);
          // Unknown error, invalidate the client, maybe it is broken.
          if (msc != null) {
            try {
              clientPool.invalidateObject(msc);
            } catch (Exception ex) {
              LOG.error("Error while invalidating a broken MetaStoreClient instance", e);
            }
          }
          return;
        }
        try {
          if (msc != null) {
            clientPool.returnObject(msc);
          }
        } catch (Exception e) {
          LOG.error("Error while returning back to the pool a MetaStoreClient instance", e);
        }
      }, initialDelay, period, TimeUnit.MILLISECONDS);
    }
Shuts down the service, by closing its underlying resources. Be aware that after shutdown this service is no
longer usable, there is no way to re-initialize it.
ql/src/java/org/apache/hadoop/hive/ql/txn/compactor/CompactionHeartbeatService.java