Skip to content

Commit e24dd3b

Browse files
authored
Merge branch 'master' into use-reg-trim-rpc-scheme
2 parents 8ccfdc5 + 89aee91 commit e24dd3b

File tree

20 files changed

+1011
-605
lines changed

20 files changed

+1011
-605
lines changed

.travis.yml

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ os:
66
# - windows # TODO: https://github.com/pingcap/kvproto/issues/355
77
- osx
88
rust:
9-
- stable
9+
# Requires nightly for now, stable can be re-enabled when 1.36 is stable.
10+
# - stable
1011
- nightly
1112
env:
1213
global:
@@ -27,14 +28,17 @@ addons:
2728
- go
2829

2930
install:
30-
- if [[ $TRAVIS_RUST_VERSION == "stable" && $TRAVIS_OS_NAME == "linux" ]]; then rustup component add rustfmt; fi
31-
- if [[ $TRAVIS_RUST_VERSION == "stable" && $TRAVIS_OS_NAME == "linux" ]]; then rustup component add clippy; fi
31+
# FIXME(#55) Remove when Clippy is fixed in current nightly
32+
- if [[ $TRAVIS_OS_NAME == "linux" ]]; then rustup toolchain install nightly-2019-05-22; fi
33+
- if [[ $TRAVIS_OS_NAME == "linux" ]]; then rustup default nightly-2019-05-22; fi
34+
- if [[ $TRAVIS_OS_NAME == "linux" ]]; then rustup component add rustfmt; fi
35+
- if [[ $TRAVIS_OS_NAME == "linux" ]]; then rustup component add clippy; fi
3236
- if [[ $TRAVIS_OS_NAME == "windows" ]]; then choco install golang cmake strawberryperl protoc; fi
3337
- if [[ $TRAVIS_OS_NAME == "windows" ]]; then export PATH="$PATH:/c/Go/bin/:/c/Program Files/CMake/bin"; fi
3438

3539
script:
36-
- if [[ $TRAVIS_RUST_VERSION == "stable" && $TRAVIS_OS_NAME == "linux" ]]; then cargo fmt -- --check; fi
37-
- if [[ $TRAVIS_RUST_VERSION == "stable" && $TRAVIS_OS_NAME == "linux" ]]; then cargo clippy -- -D clippy::all; fi
40+
- if [[ $TRAVIS_OS_NAME == "linux" ]]; then cargo fmt -- --check; fi
41+
- if [[ $TRAVIS_OS_NAME == "linux" ]]; then cargo clippy -- -D clippy::all; fi
3842
- cargo test --all -- --nocapture
3943
# For now we only run full integration tests on Linux. Here's why:
4044
# * Docker on OS X is not supported by Travis.

Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ name = "tikv_client"
2020
[dependencies]
2121
regex = "1"
2222
failure = "0.1"
23-
futures = "0.1"
24-
fxhash = "0.2"
23+
futures-preview = { version = "0.3.0-alpha.15", features = ["compat"] }
2524
grpcio = { version = "0.5.0-alpha", features = [ "secure", "prost-codec" ], default-features = false }
2625
lazy_static = "0.2.1"
2726
log = "0.3.9"
@@ -41,3 +40,5 @@ features = ["push", "process"]
4140
[dev-dependencies]
4241
clap = "2.32"
4342
tempdir = "0.3"
43+
runtime = "0.3.0-alpha.3"
44+
runtime-tokio = "0.3.0-alpha.3"

README.md

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,24 @@ With this crate you can easily connect to any TiKV deployment, interact with it,
1212

1313
This is an open source (Apache 2) project hosted by the Cloud Native Computing Foundation (CNCF) and maintained by the TiKV Authors. *We'd love it if you joined us in improving this project.*
1414

15-
## Install
15+
## Using the client
1616

17-
There are no special requirements to use this. It is a Rust 2018 edition crate supporting stable and nightly.
17+
The TiKV client is a Rust library (crate). It requires version 1.36 of the compiler and standard libraries (which will be stable from the 4th July 2019, see below for ensuring compatibility).
1818

19-
To use this crate in your project, add it as a dependency in the `Cargo.toml` of your Rust project:
19+
To use this crate in your project, add it as a dependency in your `Cargo.toml`:
2020

2121
```toml
2222
[dependencies]
2323
# ...Your other dependencies...
24-
tikv-client = "~0.1"
24+
tikv-client = { git = "https://github.com/tikv/client-rust.git" }
2525
```
2626

27+
The client requires a Git dependency until we can [publish it](https://github.com/tikv/client-rust/issues/32).
28+
29+
There are [examples](examples) which show how to use the client in a Rust program.
30+
31+
The examples and documentation use async/await syntax. This is a new feature in Rust and is currently unstable. To use async/await you'll need to add the feature flag `#![async_await]` to your crate and use a nightly compiler (see below).
32+
2733
## Access the documentation
2834

2935
We recommend using the cargo-generated documentation to browse and understand the API. We've done
@@ -37,3 +43,31 @@ You can access the documentation on your machine by running the following in any
3743
cargo doc --package tikv-client --open
3844
# If it didn't work, browse file URL it tried to open with your browser.
3945
```
46+
47+
## Toolchain versions
48+
49+
To check what version of Rust you are using, run
50+
51+
```bash
52+
rustc --version
53+
```
54+
55+
You'll see something like `rustc 1.36.0-nightly (a784a8022 2019-05-09)` where the `1.36.0` is the toolchain version, and `nightly` is the channel (stable/beta/nightly). To install another toolchain use
56+
57+
```bash
58+
rustup toolchain install nightly
59+
```
60+
61+
Where `nightly` here is the channel to add. To update your toolchains, run
62+
63+
```bash
64+
rustup update
65+
```
66+
67+
To build your project using a specified toolchain, use something like
68+
69+
```bash
70+
cargo +nightly build
71+
```
72+
73+
Where `nightly` names the toolchain (by specifying the channel, in this case).

examples/raw.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
// Copyright 2018 TiKV Project Authors. Licensed under Apache-2.0.
22

3+
#![feature(async_await, await_macro)]
4+
35
mod common;
46

57
use crate::common::parse_args;
6-
use futures::future::Future;
78
use tikv_client::{raw::Client, Config, Key, KvPair, Result, Value};
89

910
const KEY: &str = "TiKV";
1011
const VALUE: &str = "Rust";
1112

12-
fn main() -> Result<()> {
13+
#[runtime::main(runtime_tokio::Tokio)]
14+
async fn main() -> Result<()> {
1315
// You can try running this example by passing your pd endpoints
1416
// (and SSL options if necessary) through command line arguments.
1517
let args = parse_args("raw");
@@ -25,15 +27,14 @@ fn main() -> Result<()> {
2527
// When we first create a client we receive a `Connect` structure which must be resolved before
2628
// the client is actually connected and usable.
2729
let unconnnected_client = Client::new(config);
28-
let client = unconnnected_client.wait()?;
30+
let client = unconnnected_client.await?;
2931

3032
// Requests are created from the connected client. These calls return structures which
3133
// implement `Future`. This means the `Future` must be resolved before the action ever takes
3234
// place.
3335
//
3436
// Here we set the key `TiKV` to have the value `Rust` associated with it.
35-
let put_request = client.put(KEY, VALUE);
36-
put_request.wait()?; // Returns a `tikv_client::Error` on failure.
37+
client.put(KEY, VALUE).await.unwrap(); // Returns a `tikv_client::Error` on failure.
3738
println!("Put key {:?}, value {:?}.", KEY, VALUE);
3839

3940
// Unlike a standard Rust HashMap all calls take owned values. This is because under the hood
@@ -45,19 +46,19 @@ fn main() -> Result<()> {
4546
//
4647
// It is best to pass a `Vec<u8>` in terms of explictness and speed. `String`s and a few other
4748
// types are supported as well, but it all ends up as `Vec<u8>` in the end.
48-
let value: Option<Value> = client.get(KEY).wait()?;
49+
let value: Option<Value> = client.get(KEY).await?;
4950
assert_eq!(value, Some(Value::from(VALUE)));
5051
println!("Get key {:?} returned value {:?}.", Key::from(KEY), value);
5152

5253
// You can also set the `ColumnFamily` used by the request.
5354
// This is *advanced usage* and should have some special considerations.
54-
client.delete(KEY).wait().expect("Could not delete value");
55+
client.delete(KEY).await.expect("Could not delete value");
5556
println!("Key: {:?} deleted", Key::from(KEY));
5657

5758
// Here we check if the key has been deleted from the key-value store.
5859
let value: Option<Value> = client
5960
.get(KEY)
60-
.wait()
61+
.await
6162
.expect("Could not get just deleted entry");
6263
assert!(value.is_none());
6364

@@ -68,13 +69,13 @@ fn main() -> Result<()> {
6869
KvPair::from(("k2", "v2")),
6970
KvPair::from(("k3", "v3")),
7071
];
71-
client.batch_put(pairs).wait().expect("Could not put pairs");
72+
client.batch_put(pairs).await.expect("Could not put pairs");
7273

7374
// Same thing when you want to retrieve multiple values.
7475
let keys = vec![Key::from("k1"), Key::from("k2")];
7576
let values = client
7677
.batch_get(keys.clone())
77-
.wait()
78+
.await
7879
.expect("Could not get values");
7980
println!("Found values: {:?} for keys: {:?}", values, keys);
8081

@@ -85,7 +86,7 @@ fn main() -> Result<()> {
8586
let pairs = client
8687
.scan(start..=end, 10)
8788
.key_only()
88-
.wait()
89+
.await
8990
.expect("Could not scan");
9091

9192
let keys: Vec<_> = pairs.into_iter().map(|p| p.key().clone()).collect();

examples/transaction.rs

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,76 @@
11
// Copyright 2018 TiKV Project Authors. Licensed under Apache-2.0.
22

3+
#![feature(async_await, await_macro)]
4+
35
mod common;
46

57
use crate::common::parse_args;
6-
use futures::{future, Future, Stream};
8+
use futures::{
9+
future,
10+
prelude::{StreamExt, TryStreamExt},
11+
stream, TryFutureExt,
12+
};
713
use std::ops::RangeBounds;
814
use tikv_client::{
915
transaction::{Client, IsolationLevel},
1016
Config, Key, KvPair, Value,
1117
};
1218

13-
fn puts(client: &Client, pairs: impl IntoIterator<Item = impl Into<KvPair>>) {
19+
async fn puts(client: &Client, pairs: impl IntoIterator<Item = impl Into<KvPair>>) {
1420
let mut txn = client.begin();
15-
let _: Vec<()> = future::join_all(
21+
future::join_all(
1622
pairs
1723
.into_iter()
1824
.map(Into::into)
1925
.map(|p| txn.set(p.key().clone(), p.value().clone())),
2026
)
21-
.wait()
27+
.await
28+
.into_iter()
29+
.collect::<Result<Vec<()>, _>>()
2230
.expect("Could not set key value pairs");
23-
txn.commit().wait().expect("Could not commit transaction");
31+
txn.commit().await.expect("Could not commit transaction");
2432
}
2533

26-
fn get(client: &Client, key: Key) -> Value {
34+
async fn get(client: &Client, key: Key) -> Value {
2735
let txn = client.begin();
28-
txn.get(key).wait().expect("Could not get value")
36+
txn.get(key).await.expect("Could not get value")
2937
}
3038

31-
fn scan(client: &Client, range: impl RangeBounds<Key>, mut limit: usize) {
39+
// Ignore a spurious warning from rustc (https://github.com/rust-lang/rust/issues/60566).
40+
#[allow(unused_mut)]
41+
async fn scan(client: &Client, range: impl RangeBounds<Key>, mut limit: usize) {
3242
client
3343
.begin()
3444
.scan(range)
35-
.take_while(move |_| {
36-
Ok(if limit == 0 {
45+
.into_stream()
46+
.take_while(move |r| {
47+
assert!(r.is_ok(), "Could not scan keys");
48+
future::ready(if limit == 0 {
3749
false
3850
} else {
3951
limit -= 1;
4052
true
4153
})
4254
})
43-
.for_each(|pair| {
44-
println!("{:?}", pair);
45-
Ok(())
46-
})
47-
.wait()
48-
.expect("Could not scan keys");
55+
.for_each(|pair| future::ready(println!("{:?}", pair)))
56+
.await;
4957
}
5058

51-
fn dels(client: &Client, keys: impl IntoIterator<Item = Key>) {
59+
async fn dels(client: &Client, keys: impl IntoIterator<Item = Key>) {
5260
let mut txn = client.begin();
5361
txn.set_isolation_level(IsolationLevel::ReadCommitted);
54-
let _: Vec<()> = keys
55-
.into_iter()
56-
.map(|p| {
57-
txn.delete(p).wait().expect("Could not delete key");
62+
let _: Vec<()> = stream::iter(keys.into_iter())
63+
.then(|p| {
64+
txn.delete(p)
65+
.unwrap_or_else(|e| panic!("error in delete: {:?}", e))
5866
})
59-
.collect();
60-
txn.commit().wait().expect("Could not commit transaction");
67+
.collect()
68+
.await;
69+
txn.commit().await.expect("Could not commit transaction");
6170
}
6271

63-
fn main() {
72+
#[runtime::main(runtime_tokio::Tokio)]
73+
async fn main() {
6474
// You can try running this example by passing your pd endpoints
6575
// (and SSL options if necessary) through command line arguments.
6676
let args = parse_args("txn");
@@ -74,27 +84,27 @@ fn main() {
7484
};
7585

7686
let txn = Client::new(config)
77-
.wait()
87+
.await
7888
.expect("Could not connect to tikv");
7989

8090
// set
8191
let key1: Key = b"key1".to_vec().into();
8292
let value1: Value = b"value1".to_vec().into();
8393
let key2: Key = b"key2".to_vec().into();
8494
let value2: Value = b"value2".to_vec().into();
85-
puts(&txn, vec![(key1, value1), (key2, value2)]);
95+
puts(&txn, vec![(key1, value1), (key2, value2)]).await;
8696

8797
// get
8898
let key1: Key = b"key1".to_vec().into();
89-
let value1 = get(&txn, key1.clone());
99+
let value1 = get(&txn, key1.clone()).await;
90100
println!("{:?}", (key1, value1));
91101

92102
// scan
93103
let key1: Key = b"key1".to_vec().into();
94-
scan(&txn, key1.., 10);
104+
scan(&txn, key1.., 10).await;
95105

96106
// delete
97107
let key1: Key = b"key1".to_vec().into();
98108
let key2: Key = b"key2".to_vec().into();
99-
dels(&txn, vec![key1, key2]);
109+
dels(&txn, vec![key1, key2]).await;
100110
}

0 commit comments

Comments
 (0)