1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.master;
19
20 import static org.apache.hadoop.hbase.master.SplitLogManager.ResubmitDirective.CHECK;
21 import static org.apache.hadoop.hbase.master.SplitLogManager.ResubmitDirective.FORCE;
22 import static org.apache.hadoop.hbase.master.SplitLogManager.TerminationStatus.DELETED;
23 import static org.apache.hadoop.hbase.master.SplitLogManager.TerminationStatus.FAILURE;
24 import static org.apache.hadoop.hbase.master.SplitLogManager.TerminationStatus.IN_PROGRESS;
25 import static org.apache.hadoop.hbase.master.SplitLogManager.TerminationStatus.SUCCESS;
26
27 import java.io.IOException;
28 import java.io.InterruptedIOException;
29 import java.util.ArrayList;
30 import java.util.Arrays;
31 import java.util.Collections;
32 import java.util.HashSet;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.Set;
36 import java.util.concurrent.ConcurrentHashMap;
37 import java.util.concurrent.ConcurrentMap;
38 import java.util.concurrent.atomic.AtomicInteger;
39 import java.util.concurrent.locks.ReentrantLock;
40
41 import org.apache.commons.logging.Log;
42 import org.apache.commons.logging.LogFactory;
43 import org.apache.hadoop.conf.Configuration;
44 import org.apache.hadoop.fs.FileStatus;
45 import org.apache.hadoop.fs.FileSystem;
46 import org.apache.hadoop.fs.Path;
47 import org.apache.hadoop.fs.PathFilter;
48 import org.apache.hadoop.hbase.ChoreService;
49 import org.apache.hadoop.hbase.CoordinatedStateManager;
50 import org.apache.hadoop.hbase.HRegionInfo;
51 import org.apache.hadoop.hbase.ScheduledChore;
52 import org.apache.hadoop.hbase.Server;
53 import org.apache.hadoop.hbase.ServerName;
54 import org.apache.hadoop.hbase.SplitLogCounters;
55 import org.apache.hadoop.hbase.Stoppable;
56 import org.apache.hadoop.hbase.classification.InterfaceAudience;
57 import org.apache.hadoop.hbase.coordination.BaseCoordinatedStateManager;
58 import org.apache.hadoop.hbase.coordination.SplitLogManagerCoordination;
59 import org.apache.hadoop.hbase.coordination.SplitLogManagerCoordination.SplitLogManagerDetails;
60 import org.apache.hadoop.hbase.monitoring.MonitoredTask;
61 import org.apache.hadoop.hbase.monitoring.TaskMonitor;
62 import org.apache.hadoop.hbase.protobuf.generated.ZooKeeperProtos.SplitLogTask.RecoveryMode;
63 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
64 import org.apache.hadoop.hbase.util.FSUtils;
65 import org.apache.hadoop.hbase.util.Pair;
66 import org.apache.hadoop.hbase.wal.DefaultWALProvider;
67 import org.apache.hadoop.hbase.wal.WALFactory;
68
69 import com.google.common.annotations.VisibleForTesting;
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100 @InterfaceAudience.Private
101 public class SplitLogManager {
102 private static final Log LOG = LogFactory.getLog(SplitLogManager.class);
103
104 private Server server;
105
106 private final Stoppable stopper;
107 private final Configuration conf;
108 private final ChoreService choreService;
109
110 public static final int DEFAULT_UNASSIGNED_TIMEOUT = (3 * 60 * 1000);
111
112 private long unassignedTimeout;
113 private long lastTaskCreateTime = Long.MAX_VALUE;
114 private long checkRecoveringTimeThreshold = 15000;
115 private final List<Pair<Set<ServerName>, Boolean>> failedRecoveringRegionDeletions = Collections
116 .synchronizedList(new ArrayList<Pair<Set<ServerName>, Boolean>>());
117
118
119
120
121
122 protected final ReentrantLock recoveringRegionLock = new ReentrantLock();
123
124 private final ConcurrentMap<String, Task> tasks = new ConcurrentHashMap<String, Task>();
125 private TimeoutMonitor timeoutMonitor;
126
127 private volatile Set<ServerName> deadWorkers = null;
128 private final Object deadWorkersLock = new Object();
129
130
131
132
133
134
135
136
137
138
139
140 public SplitLogManager(Server server, Configuration conf, Stoppable stopper,
141 MasterServices master, ServerName serverName) throws IOException {
142 this.server = server;
143 this.conf = conf;
144 this.stopper = stopper;
145 this.choreService = new ChoreService(serverName.toString() + "_splitLogManager_");
146 if (server.getCoordinatedStateManager() != null) {
147 SplitLogManagerCoordination coordination =
148 ((BaseCoordinatedStateManager) server.getCoordinatedStateManager())
149 .getSplitLogManagerCoordination();
150 Set<String> failedDeletions = Collections.synchronizedSet(new HashSet<String>());
151 SplitLogManagerDetails details =
152 new SplitLogManagerDetails(tasks, master, failedDeletions, serverName);
153 coordination.setDetails(details);
154 coordination.init();
155
156 }
157 this.unassignedTimeout =
158 conf.getInt("hbase.splitlog.manager.unassigned.timeout", DEFAULT_UNASSIGNED_TIMEOUT);
159 this.timeoutMonitor =
160 new TimeoutMonitor(conf.getInt("hbase.splitlog.manager.timeoutmonitor.period", 1000),
161 stopper);
162 choreService.scheduleChore(timeoutMonitor);
163 }
164
165 private FileStatus[] getFileList(List<Path> logDirs, PathFilter filter) throws IOException {
166 return getFileList(conf, logDirs, filter);
167 }
168
169
170
171
172
173
174
175
176
177
178
179
180 @VisibleForTesting
181 public static FileStatus[] getFileList(final Configuration conf, final List<Path> logDirs,
182 final PathFilter filter)
183 throws IOException {
184 List<FileStatus> fileStatus = new ArrayList<FileStatus>();
185 for (Path logDir : logDirs) {
186 final FileSystem fs = logDir.getFileSystem(conf);
187 if (!fs.exists(logDir)) {
188 LOG.warn(logDir + " doesn't exist. Nothing to do!");
189 continue;
190 }
191 FileStatus[] logfiles = FSUtils.listStatus(fs, logDir, filter);
192 if (logfiles == null || logfiles.length == 0) {
193 LOG.info(logDir + " is empty dir, no logs to split");
194 } else {
195 Collections.addAll(fileStatus, logfiles);
196 }
197 }
198 FileStatus[] a = new FileStatus[fileStatus.size()];
199 return fileStatus.toArray(a);
200 }
201
202
203
204
205
206
207
208 public long splitLogDistributed(final Path logDir) throws IOException {
209 List<Path> logDirs = new ArrayList<Path>();
210 logDirs.add(logDir);
211 return splitLogDistributed(logDirs);
212 }
213
214
215
216
217
218
219
220
221
222 public long splitLogDistributed(final List<Path> logDirs) throws IOException {
223 if (logDirs.isEmpty()) {
224 return 0;
225 }
226 Set<ServerName> serverNames = new HashSet<ServerName>();
227 for (Path logDir : logDirs) {
228 try {
229 ServerName serverName = DefaultWALProvider.getServerNameFromWALDirectoryName(logDir);
230 if (serverName != null) {
231 serverNames.add(serverName);
232 }
233 } catch (IllegalArgumentException e) {
234
235 LOG.warn("Cannot parse server name from " + logDir);
236 }
237 }
238 return splitLogDistributed(serverNames, logDirs, null);
239 }
240
241
242
243
244
245
246
247
248
249
250 public long splitLogDistributed(final Set<ServerName> serverNames, final List<Path> logDirs,
251 PathFilter filter) throws IOException {
252 MonitoredTask status = TaskMonitor.get().createStatus("Doing distributed log split in " +
253 logDirs + " for serverName=" + serverNames);
254 FileStatus[] logfiles = getFileList(logDirs, filter);
255 status.setStatus("Checking directory contents...");
256 SplitLogCounters.tot_mgr_log_split_batch_start.incrementAndGet();
257 LOG.info("Started splitting " + logfiles.length + " logs in " + logDirs +
258 " for " + serverNames);
259 long t = EnvironmentEdgeManager.currentTime();
260 long totalSize = 0;
261 TaskBatch batch = new TaskBatch();
262 Boolean isMetaRecovery = (filter == null) ? null : false;
263 for (FileStatus lf : logfiles) {
264
265
266
267
268
269 totalSize += lf.getLen();
270 String pathToLog = FSUtils.removeRootPath(lf.getPath(), conf);
271 if (!enqueueSplitTask(pathToLog, batch)) {
272 throw new IOException("duplicate log split scheduled for " + lf.getPath());
273 }
274 }
275 waitForSplittingCompletion(batch, status);
276
277 if (filter == MasterFileSystem.META_FILTER
278
279
280 isMetaRecovery = true;
281 }
282 removeRecoveringRegions(serverNames, isMetaRecovery);
283
284 if (batch.done != batch.installed) {
285 batch.isDead = true;
286 SplitLogCounters.tot_mgr_log_split_batch_err.incrementAndGet();
287 LOG.warn("error while splitting logs in " + logDirs + " installed = " + batch.installed
288 + " but only " + batch.done + " done");
289 String msg = "error or interrupted while splitting logs in " + logDirs + " Task = " + batch;
290 status.abort(msg);
291 throw new IOException(msg);
292 }
293 for (Path logDir : logDirs) {
294 status.setStatus("Cleaning up log directory...");
295 final FileSystem fs = logDir.getFileSystem(conf);
296 try {
297 if (fs.exists(logDir) && !fs.delete(logDir, false)) {
298 LOG.warn("Unable to delete log src dir. Ignoring. " + logDir);
299 }
300 } catch (IOException ioe) {
301 FileStatus[] files = fs.listStatus(logDir);
302 if (files != null && files.length > 0) {
303 LOG.warn("Returning success without actually splitting and "
304 + "deleting all the log files in path " + logDir + ": "
305 + Arrays.toString(files), ioe);
306 } else {
307 LOG.warn("Unable to delete log src dir. Ignoring. " + logDir, ioe);
308 }
309 }
310 SplitLogCounters.tot_mgr_log_split_batch_success.incrementAndGet();
311 }
312 String msg =
313 "finished splitting (more than or equal to) " + totalSize + " bytes in " + batch.installed
314 + " log files in " + logDirs + " in "
315 + (EnvironmentEdgeManager.currentTime() - t) + "ms";
316 status.markComplete(msg);
317 LOG.info(msg);
318 return totalSize;
319 }
320
321
322
323
324
325
326
327 boolean enqueueSplitTask(String taskname, TaskBatch batch) {
328 lastTaskCreateTime = EnvironmentEdgeManager.currentTime();
329 String task =
330 ((BaseCoordinatedStateManager) server.getCoordinatedStateManager())
331 .getSplitLogManagerCoordination().prepareTask(taskname);
332 Task oldtask = createTaskIfAbsent(task, batch);
333 if (oldtask == null) {
334
335 ((BaseCoordinatedStateManager) server.getCoordinatedStateManager())
336 .getSplitLogManagerCoordination().submitTask(task);
337 return true;
338 }
339 return false;
340 }
341
342 private void waitForSplittingCompletion(TaskBatch batch, MonitoredTask status) {
343 synchronized (batch) {
344 while ((batch.done + batch.error) != batch.installed) {
345 try {
346 status.setStatus("Waiting for distributed tasks to finish. " + " scheduled="
347 + batch.installed + " done=" + batch.done + " error=" + batch.error);
348 int remaining = batch.installed - (batch.done + batch.error);
349 int actual = activeTasks(batch);
350 if (remaining != actual) {
351 LOG.warn("Expected " + remaining + " active tasks, but actually there are " + actual);
352 }
353 int remainingTasks =
354 ((BaseCoordinatedStateManager) server.getCoordinatedStateManager())
355 .getSplitLogManagerCoordination().remainingTasksInCoordination();
356 if (remainingTasks >= 0 && actual > remainingTasks) {
357 LOG.warn("Expected at least" + actual + " tasks remaining, but actually there are "
358 + remainingTasks);
359 }
360 if (remainingTasks == 0 || actual == 0) {
361 LOG.warn("No more task remaining, splitting "
362 + "should have completed. Remaining tasks is " + remainingTasks
363 + ", active tasks in map " + actual);
364 if (remainingTasks == 0 && actual == 0) {
365 return;
366 }
367 }
368 batch.wait(100);
369 if (stopper.isStopped()) {
370 LOG.warn("Stopped while waiting for log splits to be completed");
371 return;
372 }
373 } catch (InterruptedException e) {
374 LOG.warn("Interrupted while waiting for log splits to be completed");
375 Thread.currentThread().interrupt();
376 return;
377 }
378 }
379 }
380 }
381
382 @VisibleForTesting
383 ConcurrentMap<String, Task> getTasks() {
384 return tasks;
385 }
386
387 private int activeTasks(final TaskBatch batch) {
388 int count = 0;
389 for (Task t : tasks.values()) {
390 if (t.batch == batch && t.status == TerminationStatus.IN_PROGRESS) {
391 count++;
392 }
393 }
394 return count;
395
396 }
397
398
399
400
401
402
403
404
405 private void removeRecoveringRegions(final Set<ServerName> serverNames, Boolean isMetaRecovery) {
406 if (!isLogReplaying()) {
407
408 return;
409 }
410 if (serverNames == null || serverNames.isEmpty()) return;
411
412 Set<String> recoveredServerNameSet = new HashSet<String>();
413 for (ServerName tmpServerName : serverNames) {
414 recoveredServerNameSet.add(tmpServerName.getServerName());
415 }
416
417 this.recoveringRegionLock.lock();
418 try {
419 ((BaseCoordinatedStateManager) server.getCoordinatedStateManager())
420 .getSplitLogManagerCoordination().removeRecoveringRegions(recoveredServerNameSet,
421 isMetaRecovery);
422 } catch (IOException e) {
423 LOG.warn("removeRecoveringRegions got exception. Will retry", e);
424 if (serverNames != null && !serverNames.isEmpty()) {
425 this.failedRecoveringRegionDeletions.add(new Pair<Set<ServerName>, Boolean>(serverNames,
426 isMetaRecovery));
427 }
428 } finally {
429 this.recoveringRegionLock.unlock();
430 }
431 }
432
433
434
435
436
437
438
439 void removeStaleRecoveringRegions(final Set<ServerName> failedServers) throws IOException,
440 InterruptedIOException {
441 Set<String> knownFailedServers = new HashSet<String>();
442 if (failedServers != null) {
443 for (ServerName tmpServerName : failedServers) {
444 knownFailedServers.add(tmpServerName.getServerName());
445 }
446 }
447
448 this.recoveringRegionLock.lock();
449 try {
450 ((BaseCoordinatedStateManager) server.getCoordinatedStateManager())
451 .getSplitLogManagerCoordination().removeStaleRecoveringRegions(knownFailedServers);
452 } finally {
453 this.recoveringRegionLock.unlock();
454 }
455 }
456
457
458
459
460
461
462 private Task createTaskIfAbsent(String path, TaskBatch batch) {
463 Task oldtask;
464
465
466 Task newtask = new Task();
467 newtask.batch = batch;
468 oldtask = tasks.putIfAbsent(path, newtask);
469 if (oldtask == null) {
470 batch.installed++;
471 return null;
472 }
473
474 synchronized (oldtask) {
475 if (oldtask.isOrphan()) {
476 if (oldtask.status == SUCCESS) {
477
478
479
480
481 return (null);
482 }
483 if (oldtask.status == IN_PROGRESS) {
484 oldtask.batch = batch;
485 batch.installed++;
486 LOG.debug("Previously orphan task " + path + " is now being waited upon");
487 return null;
488 }
489 while (oldtask.status == FAILURE) {
490 LOG.debug("wait for status of task " + path + " to change to DELETED");
491 SplitLogCounters.tot_mgr_wait_for_zk_delete.incrementAndGet();
492 try {
493 oldtask.wait();
494 } catch (InterruptedException e) {
495 Thread.currentThread().interrupt();
496 LOG.warn("Interrupted when waiting for znode delete callback");
497
498 break;
499 }
500 }
501 if (oldtask.status != DELETED) {
502 LOG.warn("Failure because previously failed task"
503 + " state still present. Waiting for znode delete callback" + " path=" + path);
504 return oldtask;
505 }
506
507 Task t = tasks.putIfAbsent(path, newtask);
508 if (t == null) {
509 batch.installed++;
510 return null;
511 }
512 LOG.fatal("Logic error. Deleted task still present in tasks map");
513 assert false : "Deleted task still present in tasks map";
514 return t;
515 }
516 LOG.warn("Failure because two threads can't wait for the same task; path=" + path);
517 return oldtask;
518 }
519 }
520
521 Task findOrCreateOrphanTask(String path) {
522 Task orphanTask = new Task();
523 Task task;
524 task = tasks.putIfAbsent(path, orphanTask);
525 if (task == null) {
526 LOG.info("creating orphan task " + path);
527 SplitLogCounters.tot_mgr_orphan_task_acquired.incrementAndGet();
528 task = orphanTask;
529 }
530 return task;
531 }
532
533 public void stop() {
534 if (choreService != null) {
535 choreService.shutdown();
536 }
537 if (timeoutMonitor != null) {
538 timeoutMonitor.cancel(true);
539 }
540 }
541
542 void handleDeadWorker(ServerName workerName) {
543
544
545 synchronized (deadWorkersLock) {
546 if (deadWorkers == null) {
547 deadWorkers = new HashSet<ServerName>(100);
548 }
549 deadWorkers.add(workerName);
550 }
551 LOG.info("dead splitlog worker " + workerName);
552 }
553
554 void handleDeadWorkers(Set<ServerName> serverNames) {
555 synchronized (deadWorkersLock) {
556 if (deadWorkers == null) {
557 deadWorkers = new HashSet<ServerName>(100);
558 }
559 deadWorkers.addAll(serverNames);
560 }
561 LOG.info("dead splitlog workers " + serverNames);
562 }
563
564
565
566
567
568
569
570 public void setRecoveryMode(boolean isForInitialization) throws IOException {
571 ((BaseCoordinatedStateManager) server.getCoordinatedStateManager())
572 .getSplitLogManagerCoordination().setRecoveryMode(isForInitialization);
573
574 }
575
576 public void markRegionsRecovering(ServerName server, Set<HRegionInfo> userRegions)
577 throws InterruptedIOException, IOException {
578 if (userRegions == null || (!isLogReplaying())) {
579 return;
580 }
581 try {
582 this.recoveringRegionLock.lock();
583
584 ((BaseCoordinatedStateManager) this.server.getCoordinatedStateManager())
585 .getSplitLogManagerCoordination().markRegionsRecovering(server, userRegions);
586 } finally {
587 this.recoveringRegionLock.unlock();
588 }
589
590 }
591
592
593
594
595 public boolean isLogReplaying() {
596 CoordinatedStateManager m = server.getCoordinatedStateManager();
597 if (m == null) return false;
598 return ((BaseCoordinatedStateManager)m).getSplitLogManagerCoordination().isReplaying();
599 }
600
601
602
603
604 public boolean isLogSplitting() {
605 if (server.getCoordinatedStateManager() == null) return false;
606 return ((BaseCoordinatedStateManager) server.getCoordinatedStateManager())
607 .getSplitLogManagerCoordination().isSplitting();
608 }
609
610
611
612
613 public RecoveryMode getRecoveryMode() {
614 return ((BaseCoordinatedStateManager) server.getCoordinatedStateManager())
615 .getSplitLogManagerCoordination().getRecoveryMode();
616 }
617
618
619
620
621
622
623
624 @InterfaceAudience.Private
625 public static class TaskBatch {
626 public int installed = 0;
627 public int done = 0;
628 public int error = 0;
629 public volatile boolean isDead = false;
630
631 @Override
632 public String toString() {
633 return ("installed = " + installed + " done = " + done + " error = " + error);
634 }
635 }
636
637
638
639
640 @InterfaceAudience.Private
641 public static class Task {
642 public volatile long last_update;
643 public volatile int last_version;
644 public volatile ServerName cur_worker_name;
645 public volatile TaskBatch batch;
646 public volatile TerminationStatus status;
647 public volatile AtomicInteger incarnation = new AtomicInteger(0);
648 public final AtomicInteger unforcedResubmits = new AtomicInteger();
649 public volatile boolean resubmitThresholdReached;
650
651 @Override
652 public String toString() {
653 return ("last_update = " + last_update + " last_version = " + last_version
654 + " cur_worker_name = " + cur_worker_name + " status = " + status + " incarnation = "
655 + incarnation + " resubmits = " + unforcedResubmits.get() + " batch = " + batch);
656 }
657
658 public Task() {
659 last_version = -1;
660 status = IN_PROGRESS;
661 setUnassigned();
662 }
663
664 public boolean isOrphan() {
665 return (batch == null || batch.isDead);
666 }
667
668 public boolean isUnassigned() {
669 return (cur_worker_name == null);
670 }
671
672 public void heartbeatNoDetails(long time) {
673 last_update = time;
674 }
675
676 public void heartbeat(long time, int version, ServerName worker) {
677 last_version = version;
678 last_update = time;
679 cur_worker_name = worker;
680 }
681
682 public void setUnassigned() {
683 cur_worker_name = null;
684 last_update = -1;
685 }
686 }
687
688
689
690
691 private class TimeoutMonitor extends ScheduledChore {
692 private long lastLog = 0;
693
694 public TimeoutMonitor(final int period, Stoppable stopper) {
695 super("SplitLogManager Timeout Monitor", stopper, period);
696 }
697
698 @Override
699 protected void chore() {
700 int resubmitted = 0;
701 int unassigned = 0;
702 int tot = 0;
703 boolean found_assigned_task = false;
704 Set<ServerName> localDeadWorkers;
705
706 synchronized (deadWorkersLock) {
707 localDeadWorkers = deadWorkers;
708 deadWorkers = null;
709 }
710
711 for (Map.Entry<String, Task> e : tasks.entrySet()) {
712 String path = e.getKey();
713 Task task = e.getValue();
714 ServerName cur_worker = task.cur_worker_name;
715 tot++;
716
717
718
719
720
721 if (task.isUnassigned()) {
722 unassigned++;
723 continue;
724 }
725 found_assigned_task = true;
726 if (localDeadWorkers != null && localDeadWorkers.contains(cur_worker)) {
727 SplitLogCounters.tot_mgr_resubmit_dead_server_task.incrementAndGet();
728 if (((BaseCoordinatedStateManager) server.getCoordinatedStateManager())
729 .getSplitLogManagerCoordination().resubmitTask(path, task, FORCE)) {
730 resubmitted++;
731 } else {
732 handleDeadWorker(cur_worker);
733 LOG.warn("Failed to resubmit task " + path + " owned by dead " + cur_worker
734 + ", will retry.");
735 }
736 } else if (((BaseCoordinatedStateManager) server.getCoordinatedStateManager())
737 .getSplitLogManagerCoordination().resubmitTask(path, task, CHECK)) {
738 resubmitted++;
739 }
740 }
741 if (tot > 0) {
742 long now = EnvironmentEdgeManager.currentTime();
743 if (now > lastLog + 5000) {
744 lastLog = now;
745 LOG.info("total tasks = " + tot + " unassigned = " + unassigned + " tasks=" + tasks);
746 }
747 }
748 if (resubmitted > 0) {
749 LOG.info("resubmitted " + resubmitted + " out of " + tot + " tasks");
750 }
751
752
753
754
755
756
757
758
759
760 if (tot > 0
761 && !found_assigned_task
762 && ((EnvironmentEdgeManager.currentTime() - lastTaskCreateTime) > unassignedTimeout)) {
763 for (Map.Entry<String, Task> e : tasks.entrySet()) {
764 String key = e.getKey();
765 Task task = e.getValue();
766
767
768
769
770 if (task.isUnassigned() && (task.status != FAILURE)) {
771
772 ((BaseCoordinatedStateManager) server.getCoordinatedStateManager())
773 .getSplitLogManagerCoordination().checkTaskStillAvailable(key);
774 }
775 }
776 ((BaseCoordinatedStateManager) server.getCoordinatedStateManager())
777 .getSplitLogManagerCoordination().checkTasks();
778 SplitLogCounters.tot_mgr_resubmit_unassigned.incrementAndGet();
779 LOG.debug("resubmitting unassigned task(s) after timeout");
780 }
781 Set<String> failedDeletions =
782 ((BaseCoordinatedStateManager) server.getCoordinatedStateManager())
783 .getSplitLogManagerCoordination().getDetails().getFailedDeletions();
784
785 if (failedDeletions.size() > 0) {
786 List<String> tmpPaths = new ArrayList<String>(failedDeletions);
787 for (String tmpPath : tmpPaths) {
788
789 ((BaseCoordinatedStateManager) server.getCoordinatedStateManager())
790 .getSplitLogManagerCoordination().deleteTask(tmpPath);
791 }
792 failedDeletions.removeAll(tmpPaths);
793 }
794
795
796 long timeInterval =
797 EnvironmentEdgeManager.currentTime()
798 - ((BaseCoordinatedStateManager) server.getCoordinatedStateManager())
799 .getSplitLogManagerCoordination().getLastRecoveryTime();
800 if (!failedRecoveringRegionDeletions.isEmpty()
801 || (tot == 0 && tasks.size() == 0 && (timeInterval > checkRecoveringTimeThreshold))) {
802
803 if (!failedRecoveringRegionDeletions.isEmpty()) {
804 List<Pair<Set<ServerName>, Boolean>> previouslyFailedDeletions =
805 new ArrayList<Pair<Set<ServerName>, Boolean>>(failedRecoveringRegionDeletions);
806 failedRecoveringRegionDeletions.removeAll(previouslyFailedDeletions);
807 for (Pair<Set<ServerName>, Boolean> failedDeletion : previouslyFailedDeletions) {
808 removeRecoveringRegions(failedDeletion.getFirst(), failedDeletion.getSecond());
809 }
810 } else {
811 removeRecoveringRegions(null, null);
812 }
813 }
814 }
815 }
816
817 public enum ResubmitDirective {
818 CHECK(), FORCE();
819 }
820
821 public enum TerminationStatus {
822 IN_PROGRESS("in_progress"), SUCCESS("success"), FAILURE("failure"), DELETED("deleted");
823
824 String statusMsg;
825
826 TerminationStatus(String msg) {
827 statusMsg = msg;
828 }
829
830 @Override
831 public String toString() {
832 return statusMsg;
833 }
834 }
835 }