mirror of https://github.com/tikv/client-rust.git
Polish docs of clients and config
Signed-off-by: Nick Cameron <nrc@ncameron.org>
This commit is contained in:
parent
79d0d56193
commit
5b91ab9677
|
@ -3,22 +3,11 @@
|
|||
use serde_derive::{Deserialize, Serialize};
|
||||
use std::{path::PathBuf, time::Duration};
|
||||
|
||||
/// The configuration for either a `raw::Client` or a `transaction::Client`.
|
||||
/// The configuration for either a [`RawClient`](crate::RawClient) or a
|
||||
/// [`TransactionClient`](crate::TransactionClient).
|
||||
///
|
||||
/// Because TiKV is managed by a [PD](https://github.com/pingcap/pd/) cluster, the endpoints for PD
|
||||
/// must be provided, **not** the TiKV nodes.
|
||||
///
|
||||
/// It's important to **include more than one PD endpoint** (include all, if possible!)
|
||||
/// This helps avoid having a *single point of failure*.
|
||||
///
|
||||
/// By default, this client will use an insecure connection over instead of one protected by
|
||||
/// Transport Layer Security (TLS). Your deployment may have chosen to rely on security measures
|
||||
/// such as a private network, or a VPN layer to provide secure transmission.
|
||||
///
|
||||
/// To use a TLS secured connection, use the `with_security` function to set the required
|
||||
/// parameters.
|
||||
///
|
||||
/// TiKV does not currently offer encrypted storage (or encryption-at-rest).
|
||||
/// See also [`TransactionOptions`](crate::TransactionOptions) which provides more ways to configure
|
||||
/// requests.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||
#[serde(default)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
|
@ -43,11 +32,16 @@ impl Default for Config {
|
|||
}
|
||||
|
||||
impl Config {
|
||||
/// Set the certificate authority, certificate, and key locations for the
|
||||
/// [`Config`](Config).
|
||||
/// Set the certificate authority, certificate, and key locations for clients.
|
||||
///
|
||||
/// By default, TiKV connections do not utilize transport layer security. Enable it by setting
|
||||
/// these values.
|
||||
/// By default, this client will use an insecure connection over instead of one protected by
|
||||
/// Transport Layer Security (TLS). Your deployment may have chosen to rely on security measures
|
||||
/// such as a private network, or a VPN layer to provide secure transmission.
|
||||
///
|
||||
/// To use a TLS secured connection, use the `with_security` function to set the required
|
||||
/// parameters.
|
||||
///
|
||||
/// TiKV does not currently offer encrypted storage (or encryption-at-rest).
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
|
@ -66,16 +60,21 @@ impl Config {
|
|||
self
|
||||
}
|
||||
|
||||
/// Set the timeout for the [`Config`](Config).
|
||||
/// Set the timeout for clients.
|
||||
///
|
||||
/// The timeout is used for all requests when using or connecting to a TiKV cluster (including
|
||||
/// PD nodes). If the request does not complete within timeout, the request is cancelled and
|
||||
/// an error returned to the user.
|
||||
///
|
||||
/// The default timeout is two seconds.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust
|
||||
/// # use tikv_client::Config;
|
||||
/// # use std::time::Duration;
|
||||
/// let config = Config::default().timeout(Duration::from_secs(10));
|
||||
/// let config = Config::default().with_timeout(Duration::from_secs(10));
|
||||
/// ```
|
||||
pub fn timeout(mut self, timeout: Duration) -> Self {
|
||||
pub fn with_timeout(mut self, timeout: Duration) -> Self {
|
||||
self.timeout = timeout;
|
||||
self
|
||||
}
|
||||
|
|
20
src/lib.rs
20
src/lib.rs
|
@ -62,24 +62,32 @@
|
|||
//!
|
||||
//! Raw mode:
|
||||
//!
|
||||
//! ```rust
|
||||
//! use tikv_client::RawClient;
|
||||
//!
|
||||
//! ```rust,no_run
|
||||
//! # use tikv_client::{RawClient, Result};
|
||||
//! # use futures::prelude::*;
|
||||
//! # fn main() -> Result<()> {
|
||||
//! # futures::executor::block_on(async {
|
||||
//! let client = RawClient::new(vec!["127.0.0.1:2379"]).await?;
|
||||
//! client.put("key".to_owned(), "value".to_owned()).await?;
|
||||
//! let value = client.get("key".to_owned()).await?;
|
||||
//! # Ok(())
|
||||
//! # })}
|
||||
//! ```
|
||||
//!
|
||||
//! Transactional mode:
|
||||
//!
|
||||
//! ```rust
|
||||
//! use tikv_client::TransactionClient;
|
||||
//!
|
||||
//! ```rust,no_run
|
||||
//! # use tikv_client::{TransactionClient, Result};
|
||||
//! # use futures::prelude::*;
|
||||
//! # fn main() -> Result<()> {
|
||||
//! # futures::executor::block_on(async {
|
||||
//! let txn_client = TransactionClient::new(vec!["127.0.0.1:2379"]).await?;
|
||||
//! let mut txn = txn_client.begin_optimistic().await?;
|
||||
//! txn.put("key".to_owned(), "value".to_owned()).await?;
|
||||
//! let value = txn.get("key".to_owned()).await?;
|
||||
//! txn.commit().await?;
|
||||
//! # Ok(())
|
||||
//! # })}
|
||||
//! ```
|
||||
|
||||
#[macro_use]
|
||||
|
|
|
@ -19,7 +19,8 @@ const MAX_RAW_KV_SCAN_LIMIT: u32 = 10240;
|
|||
/// Raw requests don't need a wrapping transaction.
|
||||
/// Each request is immediately processed once executed.
|
||||
///
|
||||
/// The returned results of raw requests are [`Future`](std::future::Future)s that must be awaited to execute.
|
||||
/// The returned results of raw request methods are [`Future`](std::future::Future)s that must be
|
||||
/// awaited to execute.
|
||||
#[derive(Clone)]
|
||||
pub struct Client {
|
||||
rpc: Arc<PdRpcClient>,
|
||||
|
@ -29,14 +30,16 @@ pub struct Client {
|
|||
}
|
||||
|
||||
impl Client {
|
||||
/// Create a raw [`Client`](Client).
|
||||
/// Create a raw [`Client`] and connect to the TiKV cluster.
|
||||
///
|
||||
/// It's important to **include more than one PD endpoint** (include all, if possible!)
|
||||
/// This helps avoid having a *single point of failure*.
|
||||
/// Because TiKV is managed by a [PD](https://github.com/pingcap/pd/) cluster, the endpoints for
|
||||
/// PD must be provided, not the TiKV nodes. It's important to include more than one PD endpoint
|
||||
/// (include all endpoints, if possible), this helps avoid having a single point of failure.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// # use tikv_client::{Config, RawClient};
|
||||
/// # use tikv_client::RawClient;
|
||||
/// # use futures::prelude::*;
|
||||
/// # futures::executor::block_on(async {
|
||||
/// let client = RawClient::new(vec!["192.168.0.100"]).await.unwrap();
|
||||
|
@ -46,17 +49,23 @@ impl Client {
|
|||
Self::new_with_config(pd_endpoints, Config::default()).await
|
||||
}
|
||||
|
||||
/// Create a raw [`Client`](Client).
|
||||
/// Create a raw [`Client`] with a custom configuration, and connect to the TiKV cluster.
|
||||
///
|
||||
/// It's important to **include more than one PD endpoint** (include all, if possible!)
|
||||
/// This helps avoid having a *single point of failure*.
|
||||
/// Because TiKV is managed by a [PD](https://github.com/pingcap/pd/) cluster, the endpoints for
|
||||
/// PD must be provided, not the TiKV nodes. It's important to include more than one PD endpoint
|
||||
/// (include all endpoints, if possible), this helps avoid having a single point of failure.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// # use tikv_client::{Config, RawClient};
|
||||
/// # use futures::prelude::*;
|
||||
/// # use std::time::Duration;
|
||||
/// # futures::executor::block_on(async {
|
||||
/// let client = RawClient::new(vec!["192.168.0.100"]).await.unwrap();
|
||||
/// let client = RawClient::new_with_config(
|
||||
/// vec!["192.168.0.100"],
|
||||
/// Config::default().with_timeout(Duration::from_secs(60)),
|
||||
/// ).await.unwrap();
|
||||
/// # });
|
||||
/// ```
|
||||
pub async fn new_with_config<S: Into<String>>(
|
||||
|
@ -72,22 +81,27 @@ impl Client {
|
|||
})
|
||||
}
|
||||
|
||||
/// Set the column family of requests.
|
||||
/// Create a new client which is a clone of `self`, but which uses an explicit column family for
|
||||
/// all requests.
|
||||
///
|
||||
/// This function returns a new `Client`, requests created with it will have the
|
||||
/// supplied column family constraint. The original `Client` can still be used.
|
||||
/// This function returns a new `Client`; requests created with the new client will use the
|
||||
/// supplied column family. The original `Client` can still be used (without the new
|
||||
/// column family).
|
||||
///
|
||||
/// By default, raw client uses the `Default` column family.
|
||||
///
|
||||
/// For normal users of the raw API, you don't need to use other column families.
|
||||
/// By default, raw clients use the `Default` column family.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// # use tikv_client::{Config, RawClient, ColumnFamily};
|
||||
/// # use futures::prelude::*;
|
||||
/// # use std::convert::TryInto;
|
||||
/// # futures::executor::block_on(async {
|
||||
/// let client = RawClient::new(vec!["192.168.0.100"]).await.unwrap().with_cf(ColumnFamily::Write);
|
||||
/// let client = RawClient::new(vec!["192.168.0.100"])
|
||||
/// .await
|
||||
/// .unwrap()
|
||||
/// .with_cf(ColumnFamily::Write);
|
||||
/// // Fetch a value at "foo" from the Write CF.
|
||||
/// let get_request = client.get("foo".to_owned());
|
||||
/// # });
|
||||
/// ```
|
||||
|
@ -411,11 +425,11 @@ impl Client {
|
|||
///
|
||||
/// Once resolved this request will result in a set of scanners over the given keys.
|
||||
///
|
||||
/// **Warning**: This method is experimental. The `each_limit` parameter does not work as expected.
|
||||
/// It does not limit the number of results returned of each range,
|
||||
/// **Warning**: This method is experimental.
|
||||
/// The `each_limit` parameter 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.
|
||||
/// As a result, you may get **more than** `each_limit` key-value pairs for each range,
|
||||
/// but you should not miss any entries.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```rust,no_run
|
||||
|
|
|
@ -13,36 +13,38 @@ use crate::{
|
|||
use std::{mem, sync::Arc};
|
||||
use tikv_client_proto::{kvrpcpb, pdpb::Timestamp};
|
||||
|
||||
const SCAN_LOCK_BATCH_SIZE: u32 = 1024; // FIXME: cargo-culted value
|
||||
// FIXME: cargo-culted value
|
||||
const SCAN_LOCK_BATCH_SIZE: u32 = 1024;
|
||||
|
||||
/// The TiKV transactional `Client` is used to interact with TiKV using transactional (MVCC) requests.
|
||||
/// The TiKV transactional `Client` is used to interact with TiKV using transactional requests.
|
||||
///
|
||||
/// A [`Transaction`](crate::transaction::Transaction) provides a SQL-like interface.
|
||||
/// It begins with a [`begin_optimistic`](Client::begin_optimistic) or [`begin_pessimistic`](Client::begin_pessimistic) request
|
||||
/// and ends with a `rollback` or `commit` request.
|
||||
/// If a `Transaction` is dropped before it's rolled back or committed, it is automatically rolled back.
|
||||
/// Transactions support optimistic and pessimistic modes. For more details see the SIG-transaction
|
||||
/// [docs](https://github.com/tikv/sig-transaction/tree/master/doc/tikv#optimistic-and-pessimistic-transactions).
|
||||
///
|
||||
/// Transaction supports optimistic and pessimistic modes, for mroe deatils, check our
|
||||
/// [SIG-transaction](https://github.com/tikv/sig-transaction/tree/master/doc/tikv#optimistic-and-pessimistic-transactions).
|
||||
/// Begin a [`Transaction`] by calling [`begin_optimistic`](Client::begin_optimistic) or
|
||||
/// [`begin_pessimistic`](Client::begin_pessimistic). A transaction must be rolled back or committed.
|
||||
///
|
||||
/// Besides transaction, the client provides some utility methods:
|
||||
/// - `gc`: execute a GC process which clear stale data. It is not stablized yet.
|
||||
/// - `current_timestamp`: get the current `Timestamp`.
|
||||
/// - `snapshot`: get the [`Snapshot`](crate::transaction::Snapshot) of the database at a certain timestamp.
|
||||
/// Besides transactions, the client provides some further functionality:
|
||||
/// - `gc`: trigger a GC process which clears stale data in the cluster.
|
||||
/// - `current_timestamp`: get the current `Timestamp` from PD.
|
||||
/// - `snapshot`: get a [`Snapshot`] of the database at a specified timestamp.
|
||||
/// A `Snapshot` is a read-only transaction.
|
||||
///
|
||||
/// The returned results of transactional requests are [`Future`](std::future::Future)s that must be awaited to execute.
|
||||
/// The returned results of transactional requests are [`Future`](std::future::Future)s that must be
|
||||
/// awaited to execute.
|
||||
pub struct Client {
|
||||
pd: Arc<PdRpcClient>,
|
||||
}
|
||||
|
||||
impl Client {
|
||||
/// Creates a transactional [`Client`](Client).
|
||||
/// Create a transactional [`Client`] and connect to the TiKV cluster.
|
||||
///
|
||||
/// It's important to **include more than one PD endpoint** (include all, if possible!)
|
||||
/// This helps avoid having a *single point of failure*.
|
||||
/// Because TiKV is managed by a [PD](https://github.com/pingcap/pd/) cluster, the endpoints for
|
||||
/// PD must be provided, not the TiKV nodes. It's important to include more than one PD endpoint
|
||||
/// (include all endpoints, if possible), this helps avoid having a single point of failure.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use tikv_client::{Config, TransactionClient};
|
||||
/// use futures::prelude::*;
|
||||
|
@ -54,17 +56,22 @@ impl Client {
|
|||
Self::new_with_config(pd_endpoints, Config::default()).await
|
||||
}
|
||||
|
||||
/// Creates a transactional [`Client`](Client).
|
||||
/// Create a transactional [`Client`] with a custom configuration, and connect to the TiKV cluster.
|
||||
///
|
||||
/// It's important to **include more than one PD endpoint** (include all, if possible!)
|
||||
/// This helps avoid having a *single point of failure*.
|
||||
/// Because TiKV is managed by a [PD](https://github.com/pingcap/pd/) cluster, the endpoints for
|
||||
/// PD must be provided, not the TiKV nodes. It's important to include more than one PD endpoint
|
||||
/// (include all endpoints, if possible), this helps avoid having a single point of failure.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use tikv_client::{Config, TransactionClient};
|
||||
/// use futures::prelude::*;
|
||||
/// # futures::executor::block_on(async {
|
||||
/// let client = TransactionClient::new(vec!["192.168.0.100"]).await.unwrap();
|
||||
/// let client = TransactionClient::new_with_config(
|
||||
/// vec!["192.168.0.100"],
|
||||
/// Config::default().with_timeout(Duration::from_secs(60)),
|
||||
/// ).await.unwrap();
|
||||
/// # });
|
||||
/// ```
|
||||
pub async fn new_with_config<S: Into<String>>(
|
||||
|
@ -76,15 +83,16 @@ impl Client {
|
|||
Ok(Client { pd })
|
||||
}
|
||||
|
||||
/// Creates a new [`Transaction`](Transaction) in optimistic mode.
|
||||
/// Creates a new optimistic [`Transaction`].
|
||||
///
|
||||
/// Using the transaction you can issue commands like [`get`](Transaction::get) or [`put`](Transaction::put).
|
||||
/// Use the transaction to issue requests like [`get`](Transaction::get) or
|
||||
/// [`put`](Transaction::put).
|
||||
///
|
||||
/// Write operations do not lock data in TiKV, thus commit request may fail due to write conflict.
|
||||
///
|
||||
/// For details, check our [SIG-transaction](https://github.com/tikv/sig-transaction/tree/master/doc/tikv#optimistic-and-pessimistic-transactions).
|
||||
/// Write operations do not lock data in TiKV, thus the commit request may fail due to a write
|
||||
/// conflict.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use tikv_client::{Config, TransactionClient};
|
||||
/// use futures::prelude::*;
|
||||
|
@ -92,8 +100,7 @@ impl Client {
|
|||
/// let client = TransactionClient::new(vec!["192.168.0.100"]).await.unwrap();
|
||||
/// let mut transaction = client.begin_optimistic().await.unwrap();
|
||||
/// // ... Issue some commands.
|
||||
/// let commit = transaction.commit();
|
||||
/// let result = commit.await.unwrap();
|
||||
/// transaction.commit().await.unwrap();
|
||||
/// # });
|
||||
/// ```
|
||||
pub async fn begin_optimistic(&self) -> Result<Transaction> {
|
||||
|
@ -101,12 +108,13 @@ impl Client {
|
|||
Ok(self.new_transaction(timestamp, TransactionOptions::new_optimistic()))
|
||||
}
|
||||
|
||||
/// Creates a new [`Transaction`](Transaction) in pessimistic mode.
|
||||
/// Creates a new pessimistic [`Transaction`].
|
||||
///
|
||||
/// Write operations will lock the data until commit, thus commit requests should not suffer from write conflict.
|
||||
/// For details, check our [SIG-transaction](https://github.com/tikv/sig-transaction/tree/master/doc/tikv#optimistic-and-pessimistic-transactions).
|
||||
/// Write operations will lock the data until committed, thus commit requests should not suffer
|
||||
/// from write conflicts.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use tikv_client::{Config, TransactionClient};
|
||||
/// use futures::prelude::*;
|
||||
|
@ -114,8 +122,7 @@ impl Client {
|
|||
/// let client = TransactionClient::new(vec!["192.168.0.100"]).await.unwrap();
|
||||
/// let mut transaction = client.begin_pessimistic().await.unwrap();
|
||||
/// // ... Issue some commands.
|
||||
/// let commit = transaction.commit();
|
||||
/// let result = commit.await.unwrap();
|
||||
/// transaction.commit().await.unwrap();
|
||||
/// # });
|
||||
/// ```
|
||||
pub async fn begin_pessimistic(&self) -> Result<Transaction> {
|
||||
|
@ -123,9 +130,10 @@ impl Client {
|
|||
Ok(self.new_transaction(timestamp, TransactionOptions::new_pessimistic()))
|
||||
}
|
||||
|
||||
/// Creates a new customized [`Transaction`](Transaction).
|
||||
/// Create a new customized [`Transaction`].
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use tikv_client::{Config, TransactionClient, TransactionOptions};
|
||||
/// use futures::prelude::*;
|
||||
|
@ -136,8 +144,7 @@ impl Client {
|
|||
/// .await
|
||||
/// .unwrap();
|
||||
/// // ... Issue some commands.
|
||||
/// let commit = transaction.commit();
|
||||
/// let result = commit.await.unwrap();
|
||||
/// transaction.commit().await.unwrap();
|
||||
/// # });
|
||||
/// ```
|
||||
pub async fn begin_with_options(&self, options: TransactionOptions) -> Result<Transaction> {
|
||||
|
@ -145,14 +152,15 @@ impl Client {
|
|||
Ok(self.new_transaction(timestamp, options))
|
||||
}
|
||||
|
||||
/// Creates a new [`Snapshot`](Snapshot) at the given [`Timestamp`](Timestamp).
|
||||
/// Create a new [`Snapshot`](Snapshot) at the given [`Timestamp`](Timestamp).
|
||||
pub fn snapshot(&self, timestamp: Timestamp, options: TransactionOptions) -> Snapshot {
|
||||
Snapshot::new(self.new_transaction(timestamp, options.read_only()))
|
||||
}
|
||||
|
||||
/// Retrieves the current [`Timestamp`](Timestamp).
|
||||
/// Retrieve the current [`Timestamp`].
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use tikv_client::{Config, TransactionClient};
|
||||
/// use futures::prelude::*;
|
||||
|
@ -165,16 +173,18 @@ impl Client {
|
|||
self.pd.clone().get_timestamp().await
|
||||
}
|
||||
|
||||
/// Cleans MVCC records whose timestamp is lower than the given `timestamp` in TiKV.
|
||||
/// Trigger garbage collection (GC) of the TiKV cluster.
|
||||
///
|
||||
/// GC deletes MVCC records whose timestamp is lower than the given `safepoint`.
|
||||
///
|
||||
/// For each key, the last mutation record (unless it's a deletion) before `safepoint` is retained.
|
||||
///
|
||||
/// It is done by:
|
||||
/// 1. resolve all locks with ts <= `safepoint`
|
||||
/// 2. update safepoint to PD
|
||||
/// GC is performed by:
|
||||
/// 1. resolving all locks with timestamp <= `safepoint`
|
||||
/// 2. updating PD's known safepoint
|
||||
///
|
||||
/// This is a simplified version of [GC in TiDB](https://docs.pingcap.com/tidb/stable/garbage-collection-overview).
|
||||
/// We omit the second step "delete ranges" which is an optimization for TiDB.
|
||||
/// We skip the second step "delete ranges" which is an optimization for TiDB.
|
||||
pub async fn gc(&self, safepoint: Timestamp) -> Result<bool> {
|
||||
// scan all locks with ts <= safepoint
|
||||
let mut locks: Vec<kvrpcpb::LockInfo> = vec![];
|
||||
|
|
Loading…
Reference in New Issue