1 | /******************************************************************** |
2 | * Copyright (c) 2013 - 2014, Pivotal Inc. |
3 | * All rights reserved. |
4 | * |
5 | * Author: Zhanwei Wang |
6 | ********************************************************************/ |
7 | /******************************************************************** |
8 | * 2014 - |
9 | * open source under Apache License Version 2.0 |
10 | ********************************************************************/ |
11 | /** |
12 | * Licensed to the Apache Software Foundation (ASF) under one |
13 | * or more contributor license agreements. See the NOTICE file |
14 | * distributed with this work for additional information |
15 | * regarding copyright ownership. The ASF licenses this file |
16 | * to you under the Apache License, Version 2.0 (the |
17 | * "License"); you may not use this file except in compliance |
18 | * with the License. You may obtain a copy of the License at |
19 | * |
20 | * http://www.apache.org/licenses/LICENSE-2.0 |
21 | * |
22 | * Unless required by applicable law or agreed to in writing, software |
23 | * distributed under the License is distributed on an "AS IS" BASIS, |
24 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
25 | * See the License for the specific language governing permissions and |
26 | * limitations under the License. |
27 | */ |
28 | #ifndef _HDFS_LIBHDFS3_RPC_RPCCLIENT_H_ |
29 | #define _HDFS_LIBHDFS3_RPC_RPCCLIENT_H_ |
30 | |
31 | #include "Memory.h" |
32 | #include "RpcAuth.h" |
33 | #include "RpcCall.h" |
34 | #include "RpcChannel.h" |
35 | #include "RpcChannelKey.h" |
36 | #include "RpcConfig.h" |
37 | #include "RpcProtocolInfo.h" |
38 | #include "RpcServerInfo.h" |
39 | #include "Thread.h" |
40 | #include "Unordered.h" |
41 | |
42 | #include <vector> |
43 | |
44 | #ifdef MOCK |
45 | #include "TestRpcChannelStub.h" |
46 | #endif |
47 | |
48 | namespace Hdfs { |
49 | namespace Internal { |
50 | |
51 | class RpcClient { |
52 | public: |
53 | /** |
54 | * Destroy an RpcClient instance. |
55 | */ |
56 | virtual ~RpcClient() { |
57 | } |
58 | |
59 | /** |
60 | * Get a RPC channel, create a new one if necessary. |
61 | * @param auth Authentication information used to setup RPC connection. |
62 | * @param protocol The RPC protocol used in this call. |
63 | * @param server Remote server information. |
64 | * @param conf RPC connection configuration. |
65 | * @param once If true, the RPC channel will not be reused. |
66 | */ |
67 | virtual RpcChannel & getChannel(const RpcAuth & auth, |
68 | const RpcProtocolInfo & protocol, const RpcServerInfo & server, |
69 | const RpcConfig & conf) = 0; |
70 | |
71 | /** |
72 | * Check the RpcClient is still running. |
73 | * @return true if the RpcClient is still running. |
74 | */ |
75 | virtual bool isRunning() = 0; |
76 | |
77 | virtual std::string getClientId() const = 0; |
78 | |
79 | virtual int32_t getCallId() = 0; |
80 | |
81 | public: |
82 | static RpcClient & getClient(); |
83 | static void createSinglten(); |
84 | |
85 | private: |
86 | static once_flag once; |
87 | static shared_ptr<RpcClient> client; |
88 | }; |
89 | |
90 | class RpcClientImpl: public RpcClient { |
91 | public: |
92 | /** |
93 | * Construct a RpcClient. |
94 | */ |
95 | RpcClientImpl(); |
96 | |
97 | /** |
98 | * Destroy an RpcClient instance. |
99 | */ |
100 | ~RpcClientImpl(); |
101 | |
102 | /** |
103 | * Get a RPC channel, create a new one if necessary. |
104 | * @param auth Authentication information used to setup RPC connection. |
105 | * @param protocol The RPC protocol used in this call. |
106 | * @param server Remote server information. |
107 | * @param conf RPC connection configuration. |
108 | * @param once If true, the RPC channel will not be reused. |
109 | */ |
110 | RpcChannel & getChannel(const RpcAuth & auth, |
111 | const RpcProtocolInfo & protocol, const RpcServerInfo & server, |
112 | const RpcConfig & conf); |
113 | |
114 | /** |
115 | * Close the RPC channel. |
116 | */ |
117 | void close(); |
118 | |
119 | /** |
120 | * Check the RpcClient is still running. |
121 | * @return true if the RpcClient is still running. |
122 | */ |
123 | bool isRunning(); |
124 | |
125 | std::string getClientId() const { |
126 | return clientId; |
127 | } |
128 | |
129 | int32_t getCallId() { |
130 | static mutex mutid; |
131 | lock_guard<mutex> lock(mutid); |
132 | ++count; |
133 | count = count < std::numeric_limits<int32_t>::max() ? count : 0; |
134 | return count; |
135 | } |
136 | |
137 | private: |
138 | shared_ptr<RpcChannel> createChannelInternal( |
139 | const RpcChannelKey & key); |
140 | |
141 | void clean(); |
142 | |
143 | private: |
144 | atomic<bool> cleaning; |
145 | atomic<bool> running; |
146 | condition_variable cond; |
147 | int64_t count; |
148 | mutex mut; |
149 | std::string clientId; |
150 | thread cleaner; |
151 | unordered_map<RpcChannelKey, shared_ptr<RpcChannel> > allChannels; |
152 | |
153 | #ifdef MOCK |
154 | private: |
155 | /* |
156 | * for test |
157 | */ |
158 | Hdfs::Mock::TestRpcChannelStub * stub; |
159 | #endif |
160 | }; |
161 | |
162 | } |
163 | } |
164 | |
165 | #endif /* _HDFS_LIBHDFS3_RPC_RPCCLIENT_H_ */ |
166 | |