rust_etcd_utils/lib.rs
1//!
2//! A set of utilities for working with etcd client Rust client.
3//!
4//! The library provides API to create "managed" etcd resources, such as leases, locks, and logs.
5//!
6//! Most of the API is built on top of the etcd client library, and provides a higher-level abstraction.
7//!
8//! It is designed to be used in asynchronous Rust applications, and provides a set of utilities for working with etcd in a concurrent environment.
9//!
10//! As you start your journey with etcd you will find that the etcd client library is a bit low-level and requires a lot of boilerplate code to work with.
11//! You have to implement your own lease renewal, early lock release and you typically wants to run future against a lock lifetime.
12//!
13//! Moreover, properly managing watcher can be tricky as you have to deal with many edge cases.
14//!
15//! Also, every object has retry logic to handle transient errors when communicating with etcd.
16//! If you are using etcd in a distributed system, you will encounter transient errors such as network partition or server overload.
17//! This library provides a set of utilities to handle these errors and retry the operation.
18//!
19//! Lastly, all modules in this crate uses RAII pattern to manage resources.
20//! When you drop a resource, it will automatically release the lock or lease.
21//!
22//! # Examples
23//!
24//! For a complete example, see the [`tests`] directory.
25//!
26//! ```rust
27//! use etcd_client::Client;
28//! use rust_etcd_utils::{
29//! lock::spawn_lock_manager,
30//! }
31//!
32//! #[tokio::main]
33//! async fn main() {
34//!
35//! let etcd = Client::connect(["http://localhost:2379"], None)
36//! .await
37//! .expect("failed to connect to etcd");
38//! let (lock_manager, _lock_manager_handle) = spawn_lock_manager(etcd);
39//!
40//! let lock = lock_manager
41//! .lock("my_lock", std::time::Duration::from_secs(10))
42//! .await
43//! .expect("failed to lock");
44//!
45//! lock.scope_with(|scope| async move {
46//! // Do something WHILE YOU HOLD THE LOCK
47//! // This is a good place to do some work that requires exclusive access to a resource.
48//! // For example, you can write to a log or update a value in etcd.
49//! // If the lock is lost while you are doing this work, the future will be cancelled.
50//! ...
51//! }).await.expect("lock lost");
52//!
53//! let revoke_notif = lock.get_revoke_notify();
54//!
55//! drop(lock)); // Release the lock early
56//!
57//! // Wait for the lock to be released
58//! let _ = revoke_notif.recv().await; // The lock is released
59//! }
60//! ```
61//!
62//!
63//! [`tests`]: https://github.com/rpcpool/rust-etcd-utils/tree/main/tests
64//!
65
66///
67/// Provides an API over "managed" lease
68///
69pub mod lease;
70
71///
72/// Provides an API over "managed" lock
73///
74pub mod lock;
75
76///
77/// Utility function to manage various transient errors.
78pub mod retry;
79
80///
81/// Robust API for watching etcd changes
82pub mod watcher;
83
84///
85/// Alias for etcd revision
86pub type Revision = i64;
87
88///
89/// Provides an API over a lock-protected log
90///
91/// A log is an append-only style data structure stored on etcd, where the writer is protected by a lock.
92///
93pub mod log;
94
95///
96/// Utiltities for inter-task communication
97///
98pub mod sync;
99
100#[cfg(feature = "unstable")]
101pub mod channel;
102
103#[cfg(feature = "unstable")]
104pub mod tonic;