Skip to content

Commit 4b0e844

Browse files
authored
*: Support API v2 (part 1) (#415)
* API v2 part1 Signed-off-by: Ping Yu <[email protected]> * inplace encoding Signed-off-by: Ping Yu <[email protected]> * polish Signed-off-by: Ping Yu <[email protected]> * polish Signed-off-by: Ping Yu <[email protected]> * export proto Signed-off-by: Ping Yu <[email protected]> * fix set_context Signed-off-by: Ping Yu <[email protected]> * add Codec parameter to Transaction & Snapshot Signed-off-by: Ping Yu <[email protected]> --------- Signed-off-by: Ping Yu <[email protected]>
1 parent abf22ba commit 4b0e844

15 files changed

+314
-90
lines changed

src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@
9494

9595
pub mod backoff;
9696
#[doc(hidden)]
97+
pub mod proto; // export `proto` to enable user customized codec
98+
#[doc(hidden)]
9799
pub mod raw;
98100
pub mod request;
99101
#[doc(hidden)]
@@ -104,7 +106,6 @@ mod compat;
104106
mod config;
105107
mod kv;
106108
mod pd;
107-
mod proto;
108109
mod region;
109110
mod region_cache;
110111
mod stats;
@@ -145,6 +146,8 @@ pub use crate::raw::Client as RawClient;
145146
#[doc(inline)]
146147
pub use crate::raw::ColumnFamily;
147148
#[doc(inline)]
149+
pub use crate::request::codec;
150+
#[doc(inline)]
148151
pub use crate::request::RetryOptions;
149152
#[doc(inline)]
150153
pub use crate::timestamp::Timestamp;

src/mock.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ use crate::proto::metapb::RegionEpoch;
1818
use crate::proto::metapb::{self};
1919
use crate::region::RegionId;
2020
use crate::region::RegionWithLeader;
21+
use crate::request::codec::ApiV1TxnCodec;
2122
use crate::store::KvClient;
2223
use crate::store::KvConnect;
2324
use crate::store::RegionStore;
@@ -30,7 +31,7 @@ use crate::Timestamp;
3031

3132
/// Create a `PdRpcClient` with it's internals replaced with mocks so that the
3233
/// client can be tested without doing any RPC calls.
33-
pub async fn pd_rpc_client() -> PdRpcClient<MockKvConnect, MockCluster> {
34+
pub async fn pd_rpc_client() -> PdRpcClient<ApiV1TxnCodec, MockKvConnect, MockCluster> {
3435
let config = Config::default();
3536
PdRpcClient::new(
3637
config.clone(),
@@ -43,6 +44,7 @@ pub async fn pd_rpc_client() -> PdRpcClient<MockKvConnect, MockCluster> {
4344
))
4445
},
4546
false,
47+
Some(ApiV1TxnCodec::default()),
4648
)
4749
.await
4850
.unwrap()
@@ -71,9 +73,18 @@ pub struct MockKvConnect;
7173

7274
pub struct MockCluster;
7375

74-
#[derive(new)]
7576
pub struct MockPdClient {
7677
client: MockKvClient,
78+
codec: ApiV1TxnCodec,
79+
}
80+
81+
impl MockPdClient {
82+
pub fn new(client: MockKvClient) -> MockPdClient {
83+
MockPdClient {
84+
client,
85+
codec: ApiV1TxnCodec::default(),
86+
}
87+
}
7788
}
7889

7990
#[async_trait]
@@ -102,6 +113,7 @@ impl MockPdClient {
102113
pub fn default() -> MockPdClient {
103114
MockPdClient {
104115
client: MockKvClient::default(),
116+
codec: ApiV1TxnCodec::default(),
105117
}
106118
}
107119

@@ -165,6 +177,7 @@ impl MockPdClient {
165177

166178
#[async_trait]
167179
impl PdClient for MockPdClient {
180+
type Codec = ApiV1TxnCodec;
168181
type KvClient = MockKvClient;
169182

170183
async fn map_region_to_store(self: Arc<Self>, region: RegionWithLeader) -> Result<RegionStore> {
@@ -210,4 +223,8 @@ impl PdClient for MockPdClient {
210223
}
211224

212225
async fn invalidate_region_cache(&self, _ver_id: crate::region::RegionVerId) {}
226+
227+
fn get_codec(&self) -> &Self::Codec {
228+
&self.codec
229+
}
213230
}

src/pd/client.rs

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use crate::region::RegionId;
2020
use crate::region::RegionVerId;
2121
use crate::region::RegionWithLeader;
2222
use crate::region_cache::RegionCache;
23+
use crate::request::codec::{ApiV1TxnCodec, Codec};
2324
use crate::store::KvClient;
2425
use crate::store::KvConnect;
2526
use crate::store::RegionStore;
@@ -50,6 +51,7 @@ use crate::Timestamp;
5051
/// So if we use transactional APIs, keys in PD are encoded and PD does not know about the encoding stuff.
5152
#[async_trait]
5253
pub trait PdClient: Send + Sync + 'static {
54+
type Codec: Codec;
5355
type KvClient: KvClient + Send + Sync + 'static;
5456

5557
/// In transactional API, `region` is decoded (keys in raw format).
@@ -189,8 +191,11 @@ pub trait PdClient: Send + Sync + 'static {
189191
.boxed()
190192
}
191193

192-
fn decode_region(mut region: RegionWithLeader, enable_codec: bool) -> Result<RegionWithLeader> {
193-
if enable_codec {
194+
fn decode_region(
195+
mut region: RegionWithLeader,
196+
enable_mvcc_codec: bool,
197+
) -> Result<RegionWithLeader> {
198+
if enable_mvcc_codec {
194199
codec::decode_bytes_in_place(&mut region.region.start_key, false)?;
195200
codec::decode_bytes_in_place(&mut region.region.end_key, false)?;
196201
}
@@ -200,20 +205,30 @@ pub trait PdClient: Send + Sync + 'static {
200205
async fn update_leader(&self, ver_id: RegionVerId, leader: metapb::Peer) -> Result<()>;
201206

202207
async fn invalidate_region_cache(&self, ver_id: RegionVerId);
208+
209+
/// Get the codec carried by `PdClient`.
210+
/// The purpose of carrying the codec is to avoid passing it on so many calling paths.
211+
fn get_codec(&self) -> &Self::Codec;
203212
}
204213

205214
/// This client converts requests for the logical TiKV cluster into requests
206215
/// for a single TiKV store using PD and internal logic.
207-
pub struct PdRpcClient<KvC: KvConnect + Send + Sync + 'static = TikvConnect, Cl = Cluster> {
216+
pub struct PdRpcClient<
217+
Cod: Codec = ApiV1TxnCodec,
218+
KvC: KvConnect + Send + Sync + 'static = TikvConnect,
219+
Cl = Cluster,
220+
> {
208221
pd: Arc<RetryClient<Cl>>,
209222
kv_connect: KvC,
210223
kv_client_cache: Arc<RwLock<HashMap<String, KvC::KvClient>>>,
211-
enable_codec: bool,
224+
enable_mvcc_codec: bool,
212225
region_cache: RegionCache<RetryClient<Cl>>,
226+
codec: Option<Cod>,
213227
}
214228

215229
#[async_trait]
216-
impl<KvC: KvConnect + Send + Sync + 'static> PdClient for PdRpcClient<KvC> {
230+
impl<Cod: Codec, KvC: KvConnect + Send + Sync + 'static> PdClient for PdRpcClient<Cod, KvC> {
231+
type Codec = Cod;
217232
type KvClient = KvC::KvClient;
218233

219234
async fn map_region_to_store(self: Arc<Self>, region: RegionWithLeader) -> Result<RegionStore> {
@@ -224,20 +239,20 @@ impl<KvC: KvConnect + Send + Sync + 'static> PdClient for PdRpcClient<KvC> {
224239
}
225240

226241
async fn region_for_key(&self, key: &Key) -> Result<RegionWithLeader> {
227-
let enable_codec = self.enable_codec;
228-
let key = if enable_codec {
242+
let enable_mvcc_codec = self.enable_mvcc_codec;
243+
let key = if enable_mvcc_codec {
229244
key.to_encoded()
230245
} else {
231246
key.clone()
232247
};
233248

234249
let region = self.region_cache.get_region_by_key(&key).await?;
235-
Self::decode_region(region, enable_codec)
250+
Self::decode_region(region, enable_mvcc_codec)
236251
}
237252

238253
async fn region_for_id(&self, id: RegionId) -> Result<RegionWithLeader> {
239254
let region = self.region_cache.get_region_by_id(id).await?;
240-
Self::decode_region(region, self.enable_codec)
255+
Self::decode_region(region, self.enable_mvcc_codec)
241256
}
242257

243258
async fn get_timestamp(self: Arc<Self>) -> Result<Timestamp> {
@@ -255,31 +270,40 @@ impl<KvC: KvConnect + Send + Sync + 'static> PdClient for PdRpcClient<KvC> {
255270
async fn invalidate_region_cache(&self, ver_id: RegionVerId) {
256271
self.region_cache.invalidate_region_cache(ver_id).await
257272
}
273+
274+
fn get_codec(&self) -> &Self::Codec {
275+
self.codec
276+
.as_ref()
277+
.unwrap_or_else(|| panic!("codec not set"))
278+
}
258279
}
259280

260-
impl PdRpcClient<TikvConnect, Cluster> {
281+
impl<Cod: Codec> PdRpcClient<Cod, TikvConnect, Cluster> {
261282
pub async fn connect(
262283
pd_endpoints: &[String],
263284
config: Config,
264-
enable_codec: bool,
265-
) -> Result<PdRpcClient> {
285+
enable_mvcc_codec: bool, // TODO: infer from `codec`.
286+
codec: Option<Cod>,
287+
) -> Result<PdRpcClient<Cod>> {
266288
PdRpcClient::new(
267289
config.clone(),
268290
|security_mgr| TikvConnect::new(security_mgr, config.timeout),
269291
|security_mgr| RetryClient::connect(pd_endpoints, security_mgr, config.timeout),
270-
enable_codec,
292+
enable_mvcc_codec,
293+
codec,
271294
)
272295
.await
273296
}
274297
}
275298

276-
impl<KvC: KvConnect + Send + Sync + 'static, Cl> PdRpcClient<KvC, Cl> {
299+
impl<Cod: Codec, KvC: KvConnect + Send + Sync + 'static, Cl> PdRpcClient<Cod, KvC, Cl> {
277300
pub async fn new<PdFut, MakeKvC, MakePd>(
278301
config: Config,
279302
kv_connect: MakeKvC,
280303
pd: MakePd,
281-
enable_codec: bool,
282-
) -> Result<PdRpcClient<KvC, Cl>>
304+
enable_mvcc_codec: bool,
305+
codec: Option<Cod>,
306+
) -> Result<PdRpcClient<Cod, KvC, Cl>>
283307
where
284308
PdFut: Future<Output = Result<RetryClient<Cl>>>,
285309
MakeKvC: FnOnce(Arc<SecurityManager>) -> KvC,
@@ -301,8 +325,9 @@ impl<KvC: KvConnect + Send + Sync + 'static, Cl> PdRpcClient<KvC, Cl> {
301325
pd: pd.clone(),
302326
kv_client_cache,
303327
kv_connect: kv_connect(security_mgr),
304-
enable_codec,
328+
enable_mvcc_codec,
305329
region_cache: RegionCache::new(pd),
330+
codec,
306331
})
307332
}
308333

@@ -322,6 +347,10 @@ impl<KvC: KvConnect + Send + Sync + 'static, Cl> PdRpcClient<KvC, Cl> {
322347
Err(e) => Err(e),
323348
}
324349
}
350+
351+
pub fn set_codec(&mut self, codec: Cod) {
352+
self.codec = Some(codec);
353+
}
325354
}
326355

327356
fn make_key_range(start_key: Vec<u8>, end_key: Vec<u8>) -> kvrpcpb::KeyRange {

0 commit comments

Comments
 (0)