1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.util;
20
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.apache.hadoop.hbase.classification.InterfaceAudience;
24 import org.apache.hadoop.hbase.Stoppable;
25
26
27
28
29
30
31
32 @InterfaceAudience.Private
33 public class Sleeper {
34 private static final Log LOG = LogFactory.getLog(Sleeper.class);
35 private final int period;
36 private final Stoppable stopper;
37 private static final long MINIMAL_DELTA_FOR_LOGGING = 10000;
38
39 private final Object sleepLock = new Object();
40 private boolean triggerWake = false;
41
42
43
44
45
46
47 public Sleeper(final int sleep, final Stoppable stopper) {
48 this.period = sleep;
49 this.stopper = stopper;
50 }
51
52
53
54
55 public void sleep() {
56 sleep(System.currentTimeMillis());
57 }
58
59
60
61
62
63 public void skipSleepCycle() {
64 synchronized (sleepLock) {
65 triggerWake = true;
66 sleepLock.notifyAll();
67 }
68 }
69
70
71
72
73
74
75 public void sleep(final long startTime) {
76 if (this.stopper.isStopped()) {
77 return;
78 }
79 long now = System.currentTimeMillis();
80 long waitTime = this.period - (now - startTime);
81 if (waitTime > this.period) {
82 LOG.warn("Calculated wait time > " + this.period +
83 "; setting to this.period: " + System.currentTimeMillis() + ", " +
84 startTime);
85 waitTime = this.period;
86 }
87 while (waitTime > 0) {
88 long woke = -1;
89 try {
90 synchronized (sleepLock) {
91 if (triggerWake) break;
92 sleepLock.wait(waitTime);
93 }
94 woke = System.currentTimeMillis();
95 long slept = woke - now;
96 if (slept - this.period > MINIMAL_DELTA_FOR_LOGGING) {
97 LOG.warn("We slept " + slept + "ms instead of " + this.period +
98 "ms, this is likely due to a long " +
99 "garbage collecting pause and it's usually bad, see " +
100 "http://hbase.apache.org/book.html#trouble.rs.runtime.zkexpired");
101 }
102 } catch(InterruptedException iex) {
103
104
105 if (this.stopper.isStopped()) {
106 return;
107 }
108 }
109
110 woke = (woke == -1)? System.currentTimeMillis(): woke;
111 waitTime = this.period - (woke - startTime);
112 }
113 synchronized(sleepLock) {
114 triggerWake = false;
115 }
116 }
117
118
119
120
121 public final int getPeriod() {
122 return period;
123 }
124 }