View Javadoc

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
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
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.
17   */
18  package org.apache.hadoop.hbase.ipc;
19  
20  import com.google.protobuf.Descriptors;
21  import com.google.protobuf.Message;
22  import org.apache.hadoop.hbase.CellScanner;
23  import org.apache.hadoop.hbase.classification.InterfaceAudience;
24  import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
25  import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
26  
27  import java.io.IOException;
28  
29  /** A call waiting for a value. */
30  @InterfaceAudience.Private
31  public class Call {
32    final int id;                                 // call id
33    final Message param;                          // rpc request method param object
34    /**
35     * Optionally has cells when making call.  Optionally has cells set on response.  Used
36     * passing cells to the rpc and receiving the response.
37     */
38    CellScanner cells;
39    Message response;                             // value, null if error
40    // The return type.  Used to create shell into which we deserialize the response if any.
41    Message responseDefaultType;
42    IOException error;                            // exception, null if value
43    volatile boolean done;                                 // true when call is done
44    long startTime;
45    final Descriptors.MethodDescriptor md;
46    final int timeout; // timeout in millisecond for this call; 0 means infinite.
47  
48    protected Call(int id, final Descriptors.MethodDescriptor md, Message param,
49        final CellScanner cells, final Message responseDefaultType, int timeout) {
50      this.param = param;
51      this.md = md;
52      this.cells = cells;
53      this.startTime = EnvironmentEdgeManager.currentTime();
54      this.responseDefaultType = responseDefaultType;
55      this.id = id;
56      this.timeout = timeout;
57    }
58  
59    /**
60     * Check if the call did timeout. Set an exception (includes a notify) if it's the case.
61     * @return true if the call is on timeout, false otherwise.
62     */
63    public boolean checkAndSetTimeout() {
64      if (timeout == 0){
65        return false;
66      }
67  
68      long waitTime = EnvironmentEdgeManager.currentTime() - getStartTime();
69      if (waitTime >= timeout) {
70        IOException ie = new CallTimeoutException("Call id=" + id +
71            ", waitTime=" + waitTime + ", operationTimeout=" + timeout + " expired.");
72        setException(ie); // includes a notify
73        return true;
74      } else {
75        return false;
76      }
77    }
78  
79    public int remainingTime() {
80      if (timeout == 0) {
81        return Integer.MAX_VALUE;
82      }
83  
84      int remaining = timeout - (int) (EnvironmentEdgeManager.currentTime() - getStartTime());
85      return remaining > 0 ? remaining : 0;
86    }
87  
88    @Override
89    public String toString() {
90      return "callId: " + this.id + " methodName: " + this.md.getName() + " param {" +
91        (this.param != null? ProtobufUtil.getShortTextFormat(this.param): "") + "}";
92    }
93  
94    /** Indicate when the call is complete and the
95     * value or error are available.  Notifies by default.  */
96    protected synchronized void callComplete() {
97      this.done = true;
98      notify();                                 // notify caller
99    }
100 
101   /** Set the exception when there is an error.
102    * Notify the caller the call is done.
103    *
104    * @param error exception thrown by the call; either local or remote
105    */
106   public void setException(IOException error) {
107     this.error = error;
108     callComplete();
109   }
110 
111   /**
112    * Set the return value when there is no error.
113    * Notify the caller the call is done.
114    *
115    * @param response return value of the call.
116    * @param cells Can be null
117    */
118   public void setResponse(Message response, final CellScanner cells) {
119     this.response = response;
120     this.cells = cells;
121     callComplete();
122   }
123 
124   public long getStartTime() {
125     return this.startTime;
126   }
127 }