Skip to content

Commit 9b921e3

Browse files
author
Vincent Rouillé
authored
Merge pull request #143 from Clikengo/async
async/await: complete rewrite of foundationdb
2 parents c548133 + 93b9259 commit 9b921e3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+5249
-4910
lines changed

.travis.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,20 +27,21 @@ matrix:
2727
- rust: nightly
2828
env: RUST_BACKTRACE=full
2929

30-
- rust: nightly
30+
- rust: stable
3131
env: NAME=clippy
3232
RUST_BACKTRACE=full
3333
CLIPPY=true
3434
script:
35-
- cargo clippy --all --all-features
35+
- rustup component add clippy
36+
- cargo clippy
3637

37-
- rust: nightly
38+
- rust: stable
3839
env: NAME=rustfmt
3940
RUST_BACKTRACE=full
4041
RUSTFMT=true
4142
script:
42-
- rustup component add rustfmt-preview
43-
- cargo fmt --all -- --write-mode=diff
43+
- rustup component add rustfmt
44+
- cargo fmt --all -- --check
4445

4546
## bindingtester
4647
- rust: stable
@@ -56,13 +57,12 @@ before_install:
5657
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then scripts/install_foundationdb_linux.sh ; fi
5758
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then scripts/install_foundationdb_macos.sh ; fi
5859
- if [[ "$TRAVIS_OS_NAME" == "windows" ]]; then scripts/install_foundationdb_win64.sh ; export PATH="${PATH}:/c/Program Files/foundationdb/bin" ; fi
59-
- if [[ "$CLIPPY" == "true" ]]; then cargo install clippy --force ; fi
6060

6161
script:
6262
- cargo test --manifest-path foundationdb-sys/Cargo.toml
6363
- cargo test --manifest-path foundationdb-gen/Cargo.toml
6464
- cargo test --manifest-path foundationdb/Cargo.toml
65-
- cargo test --manifest-path foundationdb/Cargo.toml --no-default-features --features fdb-6_0
65+
- cargo test --manifest-path foundationdb/Cargo.toml --no-default-features --features fdb-6_0 --tests
6666
- cargo test --manifest-path foundationdb-bench/Cargo.toml
6767
- cargo run --manifest-path foundationdb/Cargo.toml --example class-scheduling
6868

Cargo.toml

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
[workspace]
2-
members = ["foundationdb",
3-
"foundationdb-sys",
4-
"foundationdb-gen",
5-
"foundationdb-bench"]
2+
members = [
3+
"foundationdb",
4+
"foundationdb-sys",
5+
"foundationdb-gen",
6+
"foundationdb-bench",
7+
"foundationdb-bindingtester",
8+
]
69

710
[profile.release]
811
debug = true

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@ The repo consists of multiple crates
99

1010
| Library | Status | Description |
1111
|---------|--------|-------------|
12-
| **foundationdb** | [![](http://meritbadge.herokuapp.com/foundationdb)](https://crates.io/crates/foundationdb) [![foundationdb](https://docs.rs/foundationdb/badge.svg)](https://docs.rs/foundationdb) | High level FoundationDB client API |
13-
| **foundationdb-sys** | [![](http://meritbadge.herokuapp.com/foundationdb-sys)](https://crates.io/crates/foundationdb-sys) [![foundationdb-sys](https://docs.rs/foundationdb-sys/badge.svg)](https://docs.rs/foundationdb-sys) | C API bindings for FoundationDB |
12+
| [**foundationdb**](foundationdb/README.md) | [![](http://meritbadge.herokuapp.com/foundationdb)](https://crates.io/crates/foundationdb) [![foundationdb](https://docs.rs/foundationdb/badge.svg)](https://docs.rs/foundationdb) | High level FoundationDB client API |
13+
| [**foundationdb-sys**](foundationdb-sys/README.md) | [![](http://meritbadge.herokuapp.com/foundationdb-sys)](https://crates.io/crates/foundationdb-sys) [![foundationdb-sys](https://docs.rs/foundationdb-sys/badge.svg)](https://docs.rs/foundationdb-sys) | C API bindings for FoundationDB |
1414
| **foundationdb-gen** | n/a | Code generator for common options and types of FoundationDB |
1515

16+
The current version requires rustc 1.39+ to work (async/await feature).
17+
The previous version (0.3) is still maintained and is available within the 0.3 branch.
18+
1619
## License
1720

1821
Licensed under either of

appveyor.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
os: Visual Studio 2017
1+
os: Visual Studio 2019
22

33
environment:
44
matrix:
@@ -23,6 +23,6 @@ build_script:
2323
- cargo test --manifest-path foundationdb-sys/Cargo.toml
2424
- cargo test --manifest-path foundationdb-gen/Cargo.toml
2525
- cargo test --manifest-path foundationdb/Cargo.toml
26-
- cargo test --manifest-path foundationdb/Cargo.toml --no-default-features --features fdb-6_0
26+
- cargo test --manifest-path foundationdb/Cargo.toml --no-default-features --features fdb-6_0 --tests
2727
- cargo test --manifest-path foundationdb-bench/Cargo.toml
2828
- cargo run --manifest-path foundationdb/Cargo.toml --example class-scheduling

foundationdb-bench/Cargo.toml

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
[package]
22
name = "foundationdb-bench"
3-
version = "0.1.0"
4-
authors = ["Benjamin Fry <[email protected]>"]
3+
version = "0.4.0"
4+
authors = [
5+
"Benjamin Fry <[email protected]>",
6+
"Vincent Rouillé <[email protected]>",
7+
]
8+
edition = "2018"
59

610
description = """
711
Bindings to the C api for FoundationDB
@@ -20,12 +24,12 @@ travis-ci = { repository = "bluejekyll/foundationdb-rs" }
2024

2125

2226
[dependencies]
23-
rand = "0.7"
24-
futures = "0.1"
27+
env_logger = "0.7.1"
2528
foundationdb = { version = "*", path = "../foundationdb" }
26-
stopwatch = "0"
27-
log = "0.4"
28-
env_logger = "0.6"
29-
structopt = "0.2"
29+
futures = "0.3.0"
30+
log = "0.4.8"
31+
rand = "0.7.2"
32+
stopwatch = "0.0.7"
33+
structopt = "0.3.3"
3034

3135
[build-dependencies]

foundationdb-bench/src/bin/fdb-bench.rs

Lines changed: 44 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ use rand::rngs::mock::StepRng;
1616
use stopwatch::Stopwatch;
1717
use structopt::StructOpt;
1818

19-
use fdb::error::*;
20-
use fdb::*;
19+
use crate::fdb::*;
2120

2221
#[derive(Clone)]
2322
struct Counter {
@@ -38,72 +37,9 @@ impl Counter {
3837
}
3938
}
4039

41-
struct BenchRunner {
42-
#[allow(unused)]
43-
db: Database,
44-
counter: Counter,
45-
key_buf: Vec<u8>,
46-
val_buf: Vec<u8>,
47-
rng: StepRng,
48-
trx: Option<Transaction>,
49-
trx_batch_size: usize,
50-
}
51-
52-
impl BenchRunner {
53-
fn new(db: Database, rng: StepRng, counter: Counter, opt: &Opt) -> Self {
54-
let mut key_buf = Vec::with_capacity(opt.key_len);
55-
key_buf.resize(opt.key_len, 0u8);
56-
57-
let mut val_buf = Vec::with_capacity(opt.val_len);
58-
val_buf.resize(opt.val_len, 0u8);
59-
60-
let trx = db.create_trx().expect("failed to create trx");
61-
62-
Self {
63-
db,
64-
counter,
65-
key_buf,
66-
val_buf,
67-
68-
rng,
69-
trx: Some(trx),
70-
trx_batch_size: opt.trx_batch_size,
71-
}
72-
}
73-
74-
//TODO: impl future
75-
fn run(self) -> Box<Future<Item = (), Error = Error>> {
76-
Box::new(loop_fn(self, Self::step))
77-
}
78-
79-
//TODO: impl future
80-
fn step(mut self) -> Box<Future<Item = Loop<(), Self>, Error = Error>> {
81-
let trx = self.trx.take().unwrap();
82-
83-
for _ in 0..self.trx_batch_size {
84-
self.rng.fill_bytes(&mut self.key_buf);
85-
self.rng.fill_bytes(&mut self.val_buf);
86-
self.key_buf[0] = 0x01;
87-
trx.set(&self.key_buf, &self.val_buf);
88-
}
89-
90-
let f = trx.commit().map(move |trx| {
91-
trx.reset();
92-
self.trx = Some(trx);
93-
94-
if self.counter.decr(self.trx_batch_size) {
95-
Loop::Continue(self)
96-
} else {
97-
Loop::Break(())
98-
}
99-
});
100-
Box::new(f)
101-
}
102-
}
103-
10440
#[derive(Clone)]
10541
struct Bench {
106-
db: Database,
42+
db: Arc<Database>,
10743
opt: Opt,
10844
}
10945

@@ -124,7 +60,9 @@ impl Bench {
12460
let range = start..end;
12561
let counter = counter.clone();
12662
let b = self.clone();
127-
let handle = std::thread::spawn(move || b.run_range(range, counter).wait());
63+
let handle = std::thread::spawn(move || {
64+
futures::executor::block_on(b.clone().run_range(range, counter))
65+
});
12866
handles.push(handle);
12967

13068
start = end;
@@ -146,22 +84,39 @@ impl Bench {
14684
);
14785
}
14886

149-
fn run_range(
150-
&self,
151-
r: std::ops::Range<usize>,
152-
counter: Counter,
153-
) -> Box<Future<Item = (), Error = Error>> {
154-
let runners = r
155-
.into_iter()
156-
.map(|n| {
157-
// With deterministic Rng, benchmark with same parameters will overwrite same set
158-
// of keys again, which makes benchmark result stable.
159-
let rng = StepRng::new(n as u64, 1);
160-
BenchRunner::new(self.db.clone(), rng, counter.clone(), &self.opt).run()
161-
}).collect::<Vec<_>>();
162-
163-
let f = join_all(runners).map(|_| ());
164-
Box::new(f)
87+
async fn run_range(&self, r: std::ops::Range<usize>, counter: Counter) -> FdbResult<()> {
88+
try_join_all(r.map(|n| {
89+
// With deterministic Rng, benchmark with same parameters will overwrite same set
90+
// of keys again, which makes benchmark result stable.
91+
let rng = StepRng::new(n as u64, 1);
92+
self.run_bench(rng, counter.clone())
93+
}))
94+
.await?;
95+
Ok(())
96+
}
97+
98+
async fn run_bench(&self, mut rng: StepRng, counter: Counter) -> FdbResult<()> {
99+
let mut key_buf = vec![0; self.opt.key_len];
100+
101+
let mut val_buf = vec![0; self.opt.val_len];
102+
103+
let trx_batch_size = self.opt.trx_batch_size;
104+
let mut trx = self.db.create_trx()?;
105+
106+
loop {
107+
for _ in 0..trx_batch_size {
108+
rng.fill_bytes(&mut key_buf);
109+
rng.fill_bytes(&mut val_buf);
110+
key_buf[0] = 0x01;
111+
trx.set(&key_buf, &val_buf);
112+
}
113+
114+
trx = trx.commit().await?.reset();
115+
116+
if !counter.decr(trx_batch_size) {
117+
break Ok(());
118+
}
119+
}
165120
}
166121
}
167122

@@ -189,34 +144,17 @@ struct Opt {
189144
fn main() {
190145
env_logger::init();
191146
let opt = Opt::from_args();
192-
193147
info!("opt: {:?}", opt);
194148

195-
let network = fdb::init().expect("failed to init network");
196-
197-
let handle = std::thread::spawn(move || {
198-
let error = network.run();
199-
200-
if let Err(error) = error {
201-
panic!("fdb_run_network: {}", error);
202-
}
203-
});
204-
205-
network.wait();
206-
207-
let cluster_path = fdb::default_config_path();
208-
let cluster = Cluster::new(cluster_path)
209-
.wait()
210-
.expect("failed to create cluster");
149+
let network = fdb::boot().expect("failed to init network");
211150

212-
let db = cluster
213-
.create_database()
214-
.wait()
215-
.expect("failed to get database");
151+
let db = Arc::new(
152+
futures::executor::block_on(fdb::Database::new_compat(None))
153+
.expect("failed to get database"),
154+
);
216155

217156
let bench = Bench { db, opt };
218157
bench.run();
219158

220-
network.stop().expect("failed to stop network");
221-
handle.join().expect("failed to join fdb thread");
159+
drop(network);
222160
}

foundationdb-bindingtester/Cargo.toml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
[package]
2+
name = "bindingtester"
3+
version = "0.4.0"
4+
authors = [
5+
"Benjamin Fry <[email protected]>",
6+
"Vincent Rouillé <[email protected]>",
7+
]
8+
edition = "2018"
9+
10+
description = """
11+
Bindings to the C api for FoundationDB
12+
"""
13+
14+
repository = "https://github.com/bluejekyll/foundationdb-rs"
15+
16+
readme = "README.md"
17+
keywords = ["foundationdb", "kv"]
18+
categories = ["database"]
19+
20+
license = "MIT/Apache-2.0"
21+
22+
[badges]
23+
travis-ci = { repository = "bluejekyll/foundationdb-rs" }
24+
25+
[dependencies]
26+
env_logger = "0.7.1"
27+
foundationdb = { path = "../foundationdb", features = ["uuid"] }
28+
foundationdb-sys = { version = "0.4.0", path = "../foundationdb-sys", default-features = false }
29+
futures = "0.3.0"
30+
log = "0.4.8"
31+
structopt = "0.3.3"

foundationdb-bindingtester/README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Rust FoundationDB bindingtester
2+
===============================
3+
4+
This exe implements the official FoundationDB bindingtester protocol.
5+
6+
By running `./bindingtester.py ${this_executable}`, you can test how the rust foundationdb bindings behave.
7+
8+
The following configurations are tested and should pass without any issue:
9+
10+
```
11+
./bindingtester.py --test-name scripted
12+
./bindingtester.py --num-ops 1000 --test-name api --api-version 610
13+
./bindingtester.py --num-ops 1000 --concurrency 5 --test-name api --api-version 610
14+
```

0 commit comments

Comments
 (0)