1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.errorhandling;
19
20 import java.util.Timer;
21 import java.util.TimerTask;
22
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25 import org.apache.hadoop.hbase.classification.InterfaceAudience;
26 import org.apache.hadoop.hbase.classification.InterfaceStability;
27 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
28
29
30
31
32
33
34
35
36 @InterfaceAudience.Private
37 public class TimeoutExceptionInjector {
38
39 private static final Log LOG = LogFactory.getLog(TimeoutExceptionInjector.class);
40
41 private final long maxTime;
42 private volatile boolean complete;
43 private final Timer timer;
44 private final TimerTask timerTask;
45 private long start = -1;
46
47
48
49
50
51
52
53 public TimeoutExceptionInjector(final ForeignExceptionListener listener, final long maxTime) {
54 this.maxTime = maxTime;
55 timer = new Timer();
56 timerTask = new TimerTask() {
57 @Override
58 public void run() {
59
60 synchronized (this) {
61
62 if (TimeoutExceptionInjector.this.complete) return;
63
64 TimeoutExceptionInjector.this.complete = true;
65 }
66 long end = EnvironmentEdgeManager.currentTimeMillis();
67 TimeoutException tee = new TimeoutException(
68 "Timeout caused Foreign Exception", start, end, maxTime);
69 String source = "timer-" + timer;
70 listener.receive(new ForeignException(source, tee));
71 }
72 };
73 }
74
75 public long getMaxTime() {
76 return maxTime;
77 }
78
79
80
81
82 public void complete() {
83
84
85 if (this.complete) {
86 LOG.warn("Timer already marked completed, ignoring!");
87 return;
88 }
89 LOG.debug("Marking timer as complete - no error notifications will be received for this timer.");
90 synchronized (this.timerTask) {
91 this.complete = true;
92 }
93 this.timer.cancel();
94 }
95
96
97
98
99
100
101
102
103 public synchronized void start() throws IllegalStateException {
104 if (this.start >= 0) {
105 LOG.warn("Timer already started, can't be started again. Ignoring second request.");
106 return;
107 }
108 LOG.debug("Scheduling process timer to run in: " + maxTime + " ms");
109 timer.schedule(timerTask, maxTime);
110 this.start = EnvironmentEdgeManager.currentTimeMillis();
111 }
112
113
114
115
116
117
118 public void trigger() {
119 synchronized (timerTask) {
120 if (this.complete) {
121 LOG.warn("Timer already completed, not triggering.");
122 return;
123 }
124 LOG.debug("Triggering timer immediately!");
125 this.timer.cancel();
126 this.timerTask.run();
127 }
128 }
129 }