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  
19  package org.apache.hadoop.hbase.ipc;
20  
21  import java.io.IOException;
22  import java.util.concurrent.atomic.AtomicReference;
23  
24  import org.apache.hadoop.hbase.classification.InterfaceAudience;
25  
26  import com.google.protobuf.RpcCallback;
27  import com.google.protobuf.RpcController;
28  
29  @InterfaceAudience.Private
30  public class TimeLimitedRpcController implements RpcController {
31  
32    /**
33     * The time, in ms before the call should expire.
34     */
35    protected volatile Integer callTimeout;
36    protected volatile boolean cancelled = false;
37    protected final AtomicReference<RpcCallback<Object>> cancellationCb =
38        new AtomicReference<RpcCallback<Object>>(null);
39  
40    protected final AtomicReference<RpcCallback<IOException>> failureCb =
41        new AtomicReference<RpcCallback<IOException>>(null);
42  
43    private IOException exception;
44  
45    public int getCallTimeout() {
46      if (callTimeout != null) {
47        return callTimeout;
48      } else {
49        return 0;
50      }
51    }
52  
53    public void setCallTimeout(int callTimeout) {
54      this.callTimeout = callTimeout;
55    }
56  
57    public boolean hasCallTimeout(){
58      return callTimeout != null;
59    }
60  
61    @Override
62    public String errorText() {
63      if (exception != null) {
64        return exception.getMessage();
65      } else {
66        return null;
67      }
68    }
69  
70    /**
71     * For use in async rpc clients
72     * @return true if failed
73     */
74    @Override
75    public boolean failed() {
76      return this.exception != null;
77    }
78  
79    @Override
80    public boolean isCanceled() {
81      return cancelled;
82    }
83  
84    @Override
85    public void notifyOnCancel(RpcCallback<Object> cancellationCb) {
86      this.cancellationCb.set(cancellationCb);
87      if (this.cancelled) {
88        cancellationCb.run(null);
89      }
90    }
91  
92    /**
93     * Notify a callback on error.
94     * For use in async rpc clients
95     *
96     * @param failureCb the callback to call on error
97     */
98    public void notifyOnFail(RpcCallback<IOException> failureCb) {
99      this.failureCb.set(failureCb);
100     if (this.exception != null) {
101       failureCb.run(this.exception);
102     }
103   }
104 
105   @Override
106   public void reset() {
107     exception = null;
108     cancelled = false;
109     failureCb.set(null);
110     cancellationCb.set(null);
111     callTimeout = null;
112   }
113 
114   @Override
115   public void setFailed(String reason) {
116     this.exception = new IOException(reason);
117     if (this.failureCb.get() != null) {
118       this.failureCb.get().run(this.exception);
119     }
120   }
121 
122   /**
123    * Set failed with an exception to pass on.
124    * For use in async rpc clients
125    *
126    * @param e exception to set with
127    */
128   public void setFailed(IOException e) {
129     this.exception = e;
130     if (this.failureCb.get() != null) {
131       this.failureCb.get().run(this.exception);
132     }
133   }
134 
135   @Override
136   public void startCancel() {
137     cancelled = true;
138     if (cancellationCb.get() != null) {
139       cancellationCb.get().run(null);
140     }
141   }
142 }