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