1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.ipc;
19
20 import java.util.concurrent.BlockingQueue;
21 import java.util.concurrent.atomic.AtomicInteger;
22 import org.apache.hadoop.hbase.Abortable;
23 import org.apache.hadoop.hbase.classification.InterfaceAudience;
24 import org.apache.hadoop.hbase.monitoring.MonitoredRPCHandler;
25 import org.apache.hadoop.util.StringUtils;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29
30
31
32
33 @InterfaceAudience.Private
34 public class RpcHandler extends Thread {
35 private static final Logger LOG = LoggerFactory.getLogger(RpcHandler.class);
36
37
38
39
40 final BlockingQueue<CallRunner> q;
41
42 final int handlerCount;
43 final double handlerFailureThreshhold;
44
45
46 final AtomicInteger activeHandlerCount;
47 final AtomicInteger failedHandlerCount;
48
49
50 final Abortable abortable;
51
52 private boolean running;
53
54 RpcHandler(final String name, final double handlerFailureThreshhold, final int handlerCount,
55 final BlockingQueue<CallRunner> q, final AtomicInteger activeHandlerCount,
56 final AtomicInteger failedHandlerCount, final Abortable abortable) {
57 super(name);
58 setDaemon(true);
59 this.q = q;
60 this.handlerFailureThreshhold = handlerFailureThreshhold;
61 this.activeHandlerCount = activeHandlerCount;
62 this.failedHandlerCount = failedHandlerCount;
63 this.handlerCount = handlerCount;
64 this.abortable = abortable;
65 }
66
67
68
69
70
71 protected CallRunner getCallRunner() throws InterruptedException {
72 return this.q.take();
73 }
74
75 public void stopRunning() {
76 running = false;
77 }
78
79 @Override
80 public void run() {
81 boolean interrupted = false;
82 running = true;
83 try {
84 while (running) {
85 try {
86 run(getCallRunner());
87 } catch (InterruptedException e) {
88 interrupted = true;
89 }
90 }
91 } catch (Exception e) {
92 LOG.warn(e.toString(), e);
93 throw e;
94 } finally {
95 if (interrupted) {
96 Thread.currentThread().interrupt();
97 }
98 }
99 }
100
101 private void run(CallRunner cr) {
102 MonitoredRPCHandler status = RpcServer.getStatus();
103 cr.setStatus(status);
104 try {
105 this.activeHandlerCount.incrementAndGet();
106 cr.run();
107 } catch (Throwable e) {
108 if (e instanceof Error) {
109 int failedCount = failedHandlerCount.incrementAndGet();
110 if (this.handlerFailureThreshhold >= 0
111 && failedCount > handlerCount * this.handlerFailureThreshhold) {
112 String message = "Number of failed RpcServer handler runs exceeded threshhold "
113 + this.handlerFailureThreshhold + "; reason: " + StringUtils.stringifyException(e);
114 if (abortable != null) {
115 abortable.abort(message, e);
116 } else {
117 LOG.error("Error but can't abort because abortable is null: "
118 + StringUtils.stringifyException(e));
119 throw e;
120 }
121 } else {
122 LOG.warn("Handler errors " + StringUtils.stringifyException(e));
123 }
124 } else {
125 LOG.warn("Handler exception " + StringUtils.stringifyException(e));
126 }
127 } finally {
128 this.activeHandlerCount.decrementAndGet();
129 }
130 }
131 }