HBASE-26688 Threads shared EMPTY_RESULT may lead to unexpected client job down. ...
[hbase.git] / hbase-client / src / main / java / org / apache / hadoop / hbase / ipc / Call.java
blob8d23d92433996ae9435efc9fb40232257e8458b9
1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package org.apache.hadoop.hbase.ipc;
20 import io.opentelemetry.api.trace.Span;
21 import java.io.IOException;
22 import java.util.Optional;
23 import org.apache.commons.lang3.builder.ToStringBuilder;
24 import org.apache.commons.lang3.builder.ToStringStyle;
25 import org.apache.hadoop.hbase.CellScanner;
26 import org.apache.hadoop.hbase.client.MetricsConnection;
27 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
28 import org.apache.yetus.audience.InterfaceAudience;
30 import org.apache.hbase.thirdparty.com.google.protobuf.Descriptors;
31 import org.apache.hbase.thirdparty.com.google.protobuf.Message;
32 import org.apache.hbase.thirdparty.com.google.protobuf.RpcCallback;
33 import org.apache.hbase.thirdparty.io.netty.util.Timeout;
35 import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
37 /** A call waiting for a value. */
38 @InterfaceAudience.Private
39 class Call {
40 final int id; // call id
41 final Message param; // rpc request method param object
42 /**
43 * Optionally has cells when making call. Optionally has cells set on response. Used passing cells
44 * to the rpc and receiving the response.
46 CellScanner cells;
47 @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "IS2_INCONSISTENT_SYNC",
48 justification = "Direct access is only allowed after done")
49 Message response; // value, null if error
50 // The return type. Used to create shell into which we deserialize the response if any.
51 Message responseDefaultType;
52 @edu.umd.cs.findbugs.annotations.SuppressWarnings(value = "IS2_INCONSISTENT_SYNC",
53 justification = "Direct access is only allowed after done")
54 IOException error; // exception, null if value
55 private boolean done; // true when call is done
56 final Descriptors.MethodDescriptor md;
57 final int timeout; // timeout in millisecond for this call; 0 means infinite.
58 final int priority;
59 final MetricsConnection.CallStats callStats;
60 private final RpcCallback<Call> callback;
61 final Span span;
62 Timeout timeoutTask;
64 Call(int id, final Descriptors.MethodDescriptor md, Message param,
65 final CellScanner cells, final Message responseDefaultType, int timeout, int priority,
66 RpcCallback<Call> callback, MetricsConnection.CallStats callStats) {
67 this.param = param;
68 this.md = md;
69 this.cells = cells;
70 this.callStats = callStats;
71 this.callStats.setStartTime(EnvironmentEdgeManager.currentTime());
72 this.responseDefaultType = responseDefaultType;
73 this.id = id;
74 this.timeout = timeout;
75 this.priority = priority;
76 this.callback = callback;
77 this.span = Span.current();
80 /**
81 * Builds a simplified {@link #toString()} that includes just the id and method name.
83 public String toShortString() {
84 return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
85 .append("id", id)
86 .append("methodName", md.getName())
87 .toString();
90 @Override
91 public String toString() {
92 // Call[id=32153218,methodName=Get]
93 return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
94 .appendSuper(toShortString())
95 .append("param", Optional.ofNullable(param)
96 .map(ProtobufUtil::getShortTextFormat)
97 .orElse(""))
98 .toString();
102 * called from timeoutTask, prevent self cancel
104 public void setTimeout(IOException error) {
105 synchronized (this) {
106 if (done) {
107 return;
109 this.done = true;
110 this.error = error;
112 callback.run(this);
115 private void callComplete() {
116 if (timeoutTask != null) {
117 timeoutTask.cancel();
119 callback.run(this);
123 * Set the exception when there is an error. Notify the caller the call is done.
124 * @param error exception thrown by the call; either local or remote
126 public void setException(IOException error) {
127 synchronized (this) {
128 if (done) {
129 return;
131 this.done = true;
132 this.error = error;
134 callComplete();
138 * Set the return value when there is no error. Notify the caller the call is done.
139 * @param response return value of the call.
140 * @param cells Can be null
142 public void setResponse(Message response, final CellScanner cells) {
143 synchronized (this) {
144 if (done) {
145 return;
147 this.done = true;
148 this.response = response;
149 this.cells = cells;
151 callComplete();
154 public synchronized boolean isDone() {
155 return done;
158 public long getStartTime() {
159 return this.callStats.getStartTime();