Skip to content

Commit 995fe61

Browse files
committed
Update README
Signed-off-by: Nick Cameron <nrc@ncameron.org>
1 parent 20318ab commit 995fe61

File tree

1 file changed

+77
-70
lines changed

1 file changed

+77
-70
lines changed

README.md

Lines changed: 77 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -2,127 +2,134 @@
22

33
[![Build Status](https://travis-ci.org/tikv/client-rust.svg?branch=master)](https://travis-ci.org/tikv/client-rust)
44

5-
> Currently this crate is experimental and some portions (e.g. the Transactional API) are still in active development. You're encouraged to use this library for testing and to help us find problems!
6-
75
[Docs](https://www.tikv.dev/doc/rust-client/tikv_client/)
86

9-
This crate provides a clean, ready to use client for [TiKV](https://github.com/tikv/tikv), a
10-
distributed transactional Key-Value database written in Rust.
7+
This crate provides an easy-to-use client for [TiKV](https://github.com/tikv/tikv), a distributed, transactional key-value database written in Rust.
118

12-
With this crate you can easily connect to any TiKV deployment, interact with it, and mutate the data it contains. It uses async/await internally and exposes some `async fn` APIs as well.
9+
This crate lets you connect to a TiKV cluster and use either a transactional or raw (simple get/put style without transactional consistency guarantees) API to access and update your data.
1310

14-
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.*
11+
This is an open source (Apache 2) project maintained by the TiKV Authors. We welcome community contributions, see below for more info.
1512

1613
## Getting started
1714

18-
The TiKV client is a Rust library (crate). To use this crate in your project, add following dependencies in your `Cargo.toml`:
15+
The TiKV client is a Rust library (crate). To use this crate in your project, add the following dependency to your `Cargo.toml`:
1916

2017
```toml
2118
[dependencies]
22-
tikv-client = { git = "https://github.com/tikv/client-rust.git" }
19+
tikv-client = 0.1
2320
```
2421

25-
The client requires a Git dependency until we can [publish it](https://github.com/tikv/client-rust/issues/32).
22+
Note, that you will need `tikv-client = { git = "https://github.com/tikv/client-rust.git" }` until we publish the crate (should be any day now).
2623

27-
The client provides two modes to interact with TiKV: raw and transactional.
28-
In the current version (0.0.0), the transactional API supports optimistic transactions. Pessimistic transactions are implemented but not well tested.
24+
The minimum supported version of Rust is 1.40.
2925

30-
Important note: It is **not recommended or supported** to use both the raw and transactional APIs on the same database.
26+
The general flow of using the client crate is to create either a raw or transaction client object (which can be configured) then send commands using the client object, or use it to create transactions objects. In the latter case, the transaction is built up using various commands and then committed (or rolled back).
3127

32-
### Code examples
28+
### Examples
3329

3430
Raw mode:
3531

3632
```rust
37-
let config = Config::new(vec!["127.0.0.1:2379"]);
38-
let client = RawClient::new(config).await?;
39-
client.put("key".to_owned(), "value".to_owned()).await;
40-
let value = client.get("key".to_owned()).await;
33+
use tikv_client::RawClient;
34+
35+
let client = RawClient::new(vec!["127.0.0.1:2379"]).await?;
36+
client.put("key".to_owned(), "value".to_owned()).await?;
37+
let value = client.get("key".to_owned()).await?;
4138
```
4239

4340
Transactional mode:
4441

4542
```rust
46-
let config = Config::new(vec!["127.0.0.1:2379"]);
47-
let txn_client = TransactionClient::new(config).await?;
48-
let mut txn = txn_client.begin().await?;
43+
use tikv_client::TransactionClient;
44+
45+
let txn_client = TransactionClient::new(vec!["127.0.0.1:2379"]).await?;
46+
let mut txn = txn_client.begin_optimistic().await?;
4947
txn.put("key".to_owned(), "value".to_owned()).await?;
50-
let value = txn.get("key".to_owned()).await;
48+
let value = txn.get("key".to_owned()).await?;
5149
txn.commit().await?;
5250
```
5351

54-
There are some [examples](examples) which show how to use the client in a Rust program.
52+
## API summary
5553

56-
### API
54+
The TiKV Rust client supports several levels of abstraction. The most convenient way to use the client is via `RawClient` and `TransactionClient`. This gives a very high-level API which mostly abstracts over the distributed nature of the store and has sensible defaults for all protocols. This interface can be configured, primarily when creating the client or transaction objects via the `Config` and `TransactionOptions` structs. Using some options, you can take over parts of the protocols (such as retrying failed messages) yourself.
5755

58-
#### Raw requests
56+
The lowest level of abstraction is to create and send gRPC messages directly to TiKV (and PD) nodes. The `tikv-client-store` and `tikv-client-pd` crates make this easier than using the protobuf definitions and a gRPC library directly, but give you the same level of control.
5957

60-
| Request | Main parameter type | Successful result type | Noteworthy Behavior |
61-
| -------------- | ------------------- | ---------------------- | --------------------------------------------- |
62-
| `put` | `KvPair` | `()` | |
63-
| `get` | `Key` | `Option<Value>` | |
64-
| `delete` | `Key` | `()` | |
65-
| `scan` | `BoundRange` | `Vec<KvPair>` | |
66-
| `batch_put` | `Iter<KvPair>` | `()` | |
67-
| `batch_get` | `Iter<Key>` | `Vec<KvPair>` | Skip non-existent keys; Does not retain order |
68-
| `batch_delete` | `Iter<Key>` | `()` | |
69-
| `delete_range` | `BoundRange` | `()` | |
58+
In between these levels of abstraction, you can send and receive individual messages to the TiKV cluster, but take advantage of library code for common operations such as resolving data to regions and thus nodes in the cluster, or retrying failed messages. This can be useful for testing a TiKV cluster or for some advanced use cases. See the `client_rust::request` module for this API, and `client_rust::raw::lowering` and `client_rust::transaction::lowering` for convenience methods for creating request objects.
7059

71-
#### Transactional requests
60+
The rest of this document describes only the `RawClient`/`TransactionClient` APIs.
7261

73-
| Request | Main parameter type | Successful result type | Noteworthy Behavior |
74-
| ----------- | ------------------- | ---------------------- | ------------------------------------------------------------------ |
75-
| `put` | `KvPair` | `()` | |
76-
| `get` | `Key` | `Option<value>` | |
77-
| `key_exists` | `Key` | `bool` | |
78-
| `delete` | `Key` | `()` | |
79-
| `scan` | `BoundRange` | `Iter<KvPair>` | |
80-
| `scan_keys` | `BoundRange` | `Iter<Key>` | |
81-
| `batch_get` | `Iter<Key>` | `Iter<KvPair>` | Skip non-existent keys; Does not retain order |
82-
| `lock_keys` | `Iter<Key>` | `()` | |
83-
| `gc` | `Timestamp` | `bool` | It returns whether the latest safepoint in PD equals the parameter |
62+
Important note: It is **not recommended or supported** to use both the raw and transactional APIs on the same database.
8463

85-
For detailed behavior of each request, please refer to the [doc](#Access-the-documentation).
64+
### Types
8665

87-
#### Experimental raw requests
66+
`Key`: a key in the store. `String` and `Vec<u8>` implement `Into<Key>`, so you can pass them directly into client functions.
8867

89-
You must be careful if you want to use the following request(s). Read the description for reasons.
68+
`Value`: a value in the store; just an alias of `Vec<u8>`.
9069

91-
| Request | Main parameter type | Successful result type |
92-
| ------------ | ------------------- | ---------------------- |
93-
| `batch_scan` | `Iter<BoundRange>` | `Vec<KvPair>` |
70+
`KvPair`: a pair of a `Key` and a `Value`. It provides convenience methods for conversion to and from other types.
9471

95-
The `each_limit` parameter does not work as expected. It does not limit the number of results returned of each range, instead it limits the number of results in each region of each range. As a result, you may get **more than** `each_limit` key-value pairs for each range. But you should not miss any entries.
72+
`BoundRange`: used for range related requests like `scan`. It implements `From` for Rust ranges so you can pass a Rust range of keys to the request, e.g., `client.delete_range(vec![]..)`.
9673

97-
The results of `batch_scan` are flattened. The order of ranges is retained.
74+
### Raw requests
9875

99-
### Useful types
76+
| Request | Main parameter type | Result type | Noteworthy Behavior |
77+
| -------------- | ------------------- | ---------------- | ---------------------------------------------- |
78+
| `put` | `KvPair` | | |
79+
| `get` | `Key` | `Option<Value>` | |
80+
| `delete` | `Key` | | |
81+
| `delete_range` | `BoundRange` | | |
82+
| `scan` | `BoundRange` | `Vec<KvPair>` | |
83+
| `batch_put` | `Iter<KvPair>` | | |
84+
| `batch_get` | `Iter<Key>` | `Vec<KvPair>` | Skips non-existent keys; does not retain order |
85+
| `batch_delete` | `Iter<Key>` | | |
86+
| `batch_scan` | `Iter<BoundRange>` | `Vec<KvPair>` | See docs for `each_limit` parameter behavior. The order of ranges is retained. |
10087

101-
To use the client, there are 4 types you will need.
88+
### Transactional requests
10289

103-
`Key` is simply a vector of bytes(`Vec<u8>`). `String` and `Vec<u8>` implements `Into<Key>`, so you can directly pass them to clients.
90+
| Request | Main parameter type | Result type | Noteworthy Behavior |
91+
| -------------| ------------------- | --------------- | ------------------------------------------------------------------ |
92+
| `put` | `KvPair` | | |
93+
| `get` | `Key` | `Option<value>` | |
94+
| `key_exists` | `Key` | `bool` | |
95+
| `delete` | `Key` | | |
96+
| `scan` | `BoundRange` | `Iter<KvPair>` | |
97+
| `scan_keys` | `BoundRange` | `Iter<Key>` | |
98+
| `batch_get` | `Iter<Key>` | `Iter<KvPair>` | Skips non-existent keys; does not retain order |
99+
| `lock_keys` | `Iter<Key>` | | |
100+
| `gc` | `Timestamp` | `bool` | Returns true if the latest safepoint in PD equals the parameter |
104101

105-
`Value` is just an alias of `Vec<u8>`.
106102

107-
`KvPair` is a tuple consisting of a `Key` and a `Value`. It also provides some convenience methods for conversion to and from other types.
103+
# Development and contributing
108104

109-
`BoundRange` is used for range related requests like `scan`. It implements `From` for usual ranges so you can just create a range and pass them to the request.For instance, `client.scan("k2".to_owned()..="k5".to_owned(), 5)` or `client.delete_range(vec![]..)`.
105+
We welcome your contributions! Contributing code is great, we also appreciate filing [issues](https://github.com/tikv/client-rust/issues/new) to identify bugs and provide feedback, adding tests or examples, and improvements to documentation.
110106

111-
## Access the documentation
107+
## Building and testing
112108

113-
We've done our best to include ample, tested, and understandable examples.
109+
We use the standard Cargo workflows, e.g., `cargo build` to build and `cargo test` to run unit tests. You will need to use a nightly Rust toolchain to build and run tests.
114110

115-
We recommend using the officially maintained documentation [here](https://www.tikv.dev/doc/rust-client/tikv_client/).
111+
Running integration tests or manually testing the client with a TiKV cluster is a little bit more involved. The easiest way is to use [TiUp](https://github.com/pingcap/tiup) to initialise a cluster on your local machine:
116112

117-
You can also access the documentation on your machine by running the following in any project that depends on `tikv-client`.
113+
```
114+
tiup playground nightly --db 0 --tiflash 0 --monitor false
115+
```
118116

119-
```bash
120-
cargo doc --package tikv-client --open
121-
# If it didn't work, browse file URL it tried to open with your browser.
117+
Then if you want to run integration tests:
118+
119+
```
120+
PD_ADDRS="127.0.0.1:2379" cargo test --package tikv-client --test integration_tests --features integration-tests
122121
```
123122

124-
## Minimal Rust version
123+
## Creating a PR
124+
125+
We use a standard GitHub PR workflow. We run CI on every PR and require all PRs to build without warnings (including clippy and Rustfmt warnings), pass tests, have a DCO sign-off (use `-s` when you commit, the DCO bot will guide you through completing the DCO agreement for your first PR), and have at least one review. If any of this is difficult for you, don't worry about it and ask on the PR.
126+
127+
To run CI-like tests locally, we recommend you run `cargo clippy`, `cargo test`, and `cargo fmt` before submitting your PR. See above for running integration tests, but you probably won't need to worry about this for your first few PRs.
128+
129+
Please follow PingCAP's [Rust style guide](https://pingcap.github.io/style-guide/rust/). All code PRs should include new tests or test cases.
130+
131+
## Getting help
125132

126-
This crate supports Rust 1.40 and above.
133+
If you need help, either to find something to work on, or with any technical problem, the easiest way to get it is via Slack. We monitor the client-rust (better for general client questions) and sig-transaction (better for technical questions about TiKV's transaction protocol) channels on the [tikv-wg slack](https://tikv.org/chat).
127134

128-
For development, a nightly Rust compiler is needed to compile the tests.
135+
You can also get help on GitHub issues or PRs directly. You can just ask a question; if you don't get a response, you should ping @nrc or @ekexium.

0 commit comments

Comments
 (0)