Source:
<code>public void terminate(String reason, Exception cause, boolean clearMetrics, boolean join) { if (cause == null) { LOG.info("{} Closing source because: {}", logPeerId(), this.queueId, reason); } else { LOG.error("{} Closing source because an error occurred: {}", logPeerId(), this.queueId, reason, cause); } this.sourceRunning = false; if (initThread != null && Thread.currentThread() != initThread) { initThread.interrupt(); Threads.shutdown(initThread, this.sleepForRetries); } Collection<ReplicationSourceShipper> workers = workerThreads.values(); for (ReplicationSourceShipper worker : workers) { worker.stopWorker(); if (worker.entryReader != null) { worker.entryReader.setReaderRunning(false); } if (worker.isAlive() || worker.entryReader.isAlive()) { try { Thread.sleep(this.sleepForRetries); } catch (InterruptedException e) { LOG.info("{} Interrupted while waiting to stop", logPeerId(), worker.getName()); Thread.currentThread().interrupt(); } if (worker.isAlive()) { worker.interrupt(); } if (worker.entryReader.isAlive()) { worker.entryReader.interrupt(); } } worker.clearWALEntryBatch(); } if (this.replicationEndpoint != null) { <START> this.replicationEndpoint.stop(); <END> } if (join) { for (ReplicationSourceShipper worker : workers) { Threads.shutdown(worker, this.sleepForRetries); LOG.info("{} ReplicationSourceWorker terminated", logPeerId(), worker.getName()); } if (this.replicationEndpoint != null) { try { this.replicationEndpoint.awaitTerminated(sleepForRetries * maxRetriesMultiplier, TimeUnit.MILLISECONDS); } catch (TimeoutException te) { LOG.warn("{} Got exception while waiting for endpoint to shutdown " + "for replication source : {}", logPeerId(), this.queueId, te); } } } if (clearMetrics) { if (this.metrics != null) { this.metrics.clear(); } } }</code><technical_language>If move "stop" here, HBASE-25117 problem exist</technical_language>

Target:
public void terminate(String reason, Exception cause, boolean clearMetrics, boolean join) { if (cause == null) { LOG.info("{} Closing source because: {}", logPeerId(), this.queueId, reason); } else { LOG.error("{} Closing source because an error occurred: {}", logPeerId(), this.queueId, reason, cause); } this.sourceRunning = false; if (initThread != null && Thread.currentThread() != initThread) { initThread.interrupt(); Threads.shutdown(initThread, this.sleepForRetries); } Collection<ReplicationSourceShipper> workers = workerThreads.values(); for (ReplicationSourceShipper worker : workers) { worker.stopWorker(); if(worker.entryReader != null) { worker.entryReader.setReaderRunning(false); } } if (this.replicationEndpoint != null) { this.replicationEndpoint.stop(); } for (ReplicationSourceShipper worker : workers) { if (worker.isAlive() || worker.entryReader.isAlive()) { try { Thread.sleep(this.sleepForRetries); } catch (InterruptedException e) { LOG.info("{} Interrupted while waiting to stop", logPeerId(), worker.getName()); Thread.currentThread().interrupt(); } if (worker.isAlive()) { worker.interrupt(); } if (worker.entryReader.isAlive()) { worker.entryReader.interrupt(); } } worker.clearWALEntryBatch(); } if (join) { for (ReplicationSourceShipper worker : workers) { Threads.shutdown(worker, this.sleepForRetries); LOG.info("{} ReplicationSourceWorker terminated", logPeerId(), worker.getName()); } if (this.replicationEndpoint != null) { try { this.replicationEndpoint.awaitTerminated(sleepForRetries * maxRetriesMultiplier, TimeUnit.MILLISECONDS); } catch (TimeoutException te) { LOG.warn("{} Got exception while waiting for endpoint to shutdown " + "for replication source : {}", logPeerId(), this.queueId, te); } } } if (clearMetrics) { if (this.metrics != null) { this.metrics.clear(); } } }