Skip to content

Adding derive macros to parse structs to bins and values #126

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 44 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
e216f3b
implemented async core library
jonas32 Aug 10, 2021
8ef0e9c
Updated GH Actions to build with rt flags
jonas32 Aug 10, 2021
e839ff3
Started to rewrite tests (not working yet)
jonas32 Aug 12, 2021
506208b
batch is temporary removed, tests for all other functions are fine
jonas32 Aug 13, 2021
c6986b9
all tests are working
jonas32 Aug 13, 2021
e2b50d2
testing against older aerospike version
jonas32 Aug 13, 2021
e719714
testing with aerospike config
jonas32 Aug 13, 2021
ee976dd
removed aerospike config because docker image does not support it
jonas32 Aug 13, 2021
45810dd
GH Actions has expiring records active in aerospike
jonas32 Aug 13, 2021
73a0e3e
Fixed the wrong test...
jonas32 Aug 13, 2021
1afcc77
Changed second void time check
jonas32 Aug 13, 2021
a1cfa38
updated README.md
jonas32 Aug 13, 2021
4489e70
updated README.md
jonas32 Aug 13, 2021
35c3ce1
fixed some doc tests
jonas32 Aug 13, 2021
0338a00
Some code cleanup
jonas32 Aug 13, 2021
abde25f
Removed unused crates and changed build script
jonas32 Aug 13, 2021
ef57514
Removed unused crates
jonas32 Aug 14, 2021
2e230b1
Restructured the CI file to remove redundant parts
jonas32 Aug 14, 2021
c18c473
Added runtimes to appveyor build
jonas32 Aug 14, 2021
7f7dad0
Added sync API
jonas32 Aug 14, 2021
9ea5c18
Updated README.md for feature selection and fixed reexport of the aer…
jonas32 Aug 14, 2021
d5cb19e
Run CI in debug mode to find out why async-std gets stuck
jonas32 Aug 15, 2021
faba4b9
Reduced the number of new connections opened in the test due to new a…
jonas32 Aug 15, 2021
dab600b
Trigger CI again to make sure the previous run was no false positive
jonas32 Aug 15, 2021
a62d013
Merge branch 'master' into async
jonas32 Oct 16, 2021
1fca119
Fixed conflicts for latest master updates and merged the new auth/par…
jonas32 Oct 16, 2021
4e20184
Fixed compiler warnings
jonas32 Oct 16, 2021
0aa5531
Split CI to build all possible variations
jonas32 Oct 16, 2021
7c9ca08
Fixed typo in the CI file
jonas32 Oct 16, 2021
a997ff6
Removed sync unit testing from the CI
jonas32 Oct 16, 2021
136fcc6
Fixed wrong quotes
jonas32 Oct 16, 2021
a032c9c
Merge branch 'master' into async
jonas32 Oct 22, 2021
36f1881
Merge branch 'master' into async
jonas32 Oct 22, 2021
030ad4e
merged with 5.6 expressions
jonas32 Oct 22, 2021
c2f878a
debugging the missing feature
jonas32 Nov 4, 2021
ec05865
replaced blocking thread sleeps
jonas32 Nov 23, 2021
2602b65
fixed unused Results and clippy errors
jonas32 Mar 4, 2022
a35af2e
fixed task sleep
jonas32 Mar 4, 2022
6c0ea7e
optimized conn pool usage
jonas32 Mar 4, 2022
f0366d3
removed unused lifetime in batch_executor.rs
jonas32 Mar 4, 2022
cdff64b
Fixed Float serialization
jonas32 Mar 30, 2022
e1f95e5
Added derive macros to parse structs into Bins and Values
jonas32 Sep 11, 2022
a9ece1d
Added derive macros to parse structs into Bins and Values
jonas32 Sep 11, 2022
de99189
removed in-macro import of hashmap
jonas32 Sep 11, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -119,5 +119,5 @@ build: false
#directly or perform other testing commands. Rust will automatically be placed in the PATH
# environment variable.
test_script:
- cargo test --lib --verbose %cargoflags%
- cargo test --lib --features "serialization" --verbose %cargoflags%
- cargo test --lib --verbose --features "rt-tokio" %cargoflags%
- cargo test --lib --verbose --features "rt-async-std" %cargoflags%
25 changes: 9 additions & 16 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Aerospike Node.js Client Tests
name: Aerospike Rust Client Tests

on:
push:
Expand All @@ -22,6 +22,8 @@ jobs:
strategy:
matrix:
rust: [stable, nightly]
runtime: [rt-tokio, rt-async-std]
version: [async, sync]

steps:
- uses: actions/checkout@v2
Expand All @@ -33,19 +35,10 @@ jobs:
- run: rustc --version
- name: Set up Aerospike Database
uses: reugn/github-action-aerospike@v1
- name: Clear cache
run: rm -rf target/debug/deps/*aerospike*
- name: Build
run: cargo build --verbose
- name: Clear cache before building
run: rm -rf target/debug/deps/*
- name: Build client
run: cargo build --verbose --no-default-features --features serialization,${{ matrix.version }},${{ matrix.runtime }} # Turn off default features since async is default and this also builds sync
- name: Run tests
run: cargo test --verbose
- name: Build docs
run: rustdoc -L target/debug/deps/ --test README.md
- name: Clear cache
run: rm -rf target/debug/deps/*aerospike*
- name: Build - with serialization
run: cargo build --verbose --features "serialization"
- name: Run tests - with serialization
run: cargo test --verbose --features "serialization"
- name: Build docs - with serialization
run: rustdoc -L target/debug/deps/ --test README.md
if: matrix.version == 'async' # Unit tests only include the async interface
run: cargo test --verbose --no-default-features --features serialization,${{ matrix.version }},${{ matrix.runtime }} # Turn off default features since async is default and this also builds sync
42 changes: 22 additions & 20 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,31 +23,33 @@ travis-ci = { repository = "aerospike/aerospike-client-rust" }
appveyor = { repository = "aerospike/aerospike-client-rust" }

[dependencies]
log = "0.4"
byteorder = "1.3"
ripemd160 = "0.8"
base64 = "0.11"
crossbeam-queue = "0.2"
rand = "0.7"
scoped-pool = "1.0"
lazy_static = "1.4"
error-chain = "0.12"
parking_lot = "0.9"
pwhash = "0.3"
serde = { version = "1.0", features = ["derive"], optional = true }
aerospike-core = {path = "./aerospike-core", optional = true}
aerospike-sync = {path = "./aerospike-sync", optional = true}
aerospike-macro = {path = "./aerospike-macro", optional = true}

[features]
serialization = ["serde"]

[dev-dependencies]
env_logger = "0.7"
hex = "0.4"
bencher = "0.1"
serde_json = "1.0"
default = ["async", "serialization"]
serialization = ["aerospike-core/serialization"]
async = ["aerospike-core"]
sync = ["aerospike-sync"]
rt-tokio = ["aerospike-core/rt-tokio", "aerospike-macro/rt-tokio"]
rt-async-std = ["aerospike-core/rt-async-std", "aerospike-macro/rt-async-std"]

[[bench]]
name = "client_server"
harness = false

[workspace]
members = ["tools/benchmark"]
members = ["tools/benchmark", "aerospike-core", "aerospike-rt", "aerospike-sync", "aerospike-macro"]

[dev-dependencies]
env_logger = "0.7"
hex = "0.4"
bencher = "0.1"
serde_json = "1.0"
rand = "0.7"
lazy_static = "1.4"
aerospike-macro = {path = "./aerospike-macro"}
aerospike-rt = {path = "./aerospike-rt"}
futures = {version = "0.3.16" }
tokio = { version = "1.10.0", features = ["full"] }
48 changes: 33 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,41 @@ The current release supports Aerospike version v5.6 and later. Take a look at th
<a name="Usage"></a>
## Usage:

Add one of the following to your cargo file
```toml
# Async API with tokio Runtime
aerospike = { version = "<version>", features = ["rt-tokio"]}
# Async API with async-std runtime
aerospike = { version = "<version>", features = ["rt-async-std"]}

# The library still supports the old sync interface, but it will be deprecated in the future.
# This is only for compatibility reasons and will be removed in a later stage.

# Sync API with tokio
aerospike = { version = "<version>", default-features = false, features = ["rt-tokio", "sync"]}
# Sync API with async-std
aerospike = { version = "<version>", default-features = false, features = ["rt-async-std", "sync"]}
```

The following is a very simple example of CRUD operations in an Aerospike database.

```rust
```rust,edition2018
#[macro_use]
extern crate aerospike;
extern crate tokio;

use std::env;
use std::time::Instant;

use aerospike::{Bins, Client, ClientPolicy, ReadPolicy, WritePolicy};
use aerospike::operations;

fn main() {
#[tokio::main]
async fn main() {
let cpolicy = ClientPolicy::default();
let hosts = env::var("AEROSPIKE_HOSTS")
.unwrap_or(String::from("127.0.0.1:3000"));
let client = Client::new(&cpolicy, &hosts)
let client = Client::new(&cpolicy, &hosts).await
.expect("Failed to connect to cluster");

let now = Instant::now();
Expand All @@ -50,29 +68,29 @@ fn main() {
as_bin!("int", 999),
as_bin!("str", "Hello, World!"),
];
client.put(&wpolicy, &key, &bins).unwrap();
let rec = client.get(&rpolicy, &key, Bins::All);
client.put(&wpolicy, &key, &bins).await.unwrap();
let rec = client.get(&rpolicy, &key, Bins::All).await;
println!("Record: {}", rec.unwrap());

client.touch(&wpolicy, &key).unwrap();
let rec = client.get(&rpolicy, &key, Bins::All);
client.touch(&wpolicy, &key).await.unwrap();
let rec = client.get(&rpolicy, &key, Bins::All).await;
println!("Record: {}", rec.unwrap());

let rec = client.get(&rpolicy, &key, Bins::None);
let rec = client.get(&rpolicy, &key, Bins::None).await;
println!("Record Header: {}", rec.unwrap());

let exists = client.exists(&wpolicy, &key).unwrap();
let exists = client.exists(&wpolicy, &key).await.unwrap();
println!("exists: {}", exists);

let bin = as_bin!("int", "123");
let ops = &vec![operations::put(&bin), operations::get()];
let op_rec = client.operate(&wpolicy, &key, ops);
let op_rec = client.operate(&wpolicy, &key, ops).await;
println!("operate: {}", op_rec.unwrap());

let existed = client.delete(&wpolicy, &key).unwrap();
let existed = client.delete(&wpolicy, &key).await.unwrap();
println!("existed (should be true): {}", existed);

let existed = client.delete(&wpolicy, &key).unwrap();
let existed = client.delete(&wpolicy, &key).await.unwrap();
println!("existed (should be false): {}", existed);

println!("total time: {:?}", now.elapsed());
Expand Down Expand Up @@ -100,19 +118,19 @@ To run all the test cases:

```shell
$ export AEROSPIKE_HOSTS=127.0.0.1:3000
$ cargo test
$ cargo test --features <runtime>
```

To enable debug logging for the `aerospike` crate:

```shell
$ RUST_LOG=aerospike=debug cargo test
$ RUST_LOG=aerospike=debug cargo test --features <runtime>
```

To enable backtraces set the `RUST_BACKTRACE` environment variable:

```shell
$ RUST_BACKTRACE=1 cargo test
$ RUST_BACKTRACE=1 cargo test --features <runtime>
```

<a name="Benchmarks"></a>
Expand Down
34 changes: 34 additions & 0 deletions aerospike-core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[package]
name = "aerospike-core"
version = "0.1.0"
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
log = "0.4"
byteorder = "1.3"
ripemd160 = "0.8"
base64 = "0.11"
crossbeam-queue = "0.2"
rand = "0.7"
lazy_static = "1.4"
error-chain = "0.12"
pwhash = "0.3"
serde = { version = "1.0", features = ["derive"], optional = true }
aerospike-rt = {path = "../aerospike-rt"}
aerospike-macro = {path = "../aerospike-macro"}
futures = {version = "0.3.16" }
async-trait = "0.1.51"

[features]
serialization = ["serde"]
rt-tokio = ["aerospike-rt/rt-tokio"]
rt-async-std = ["aerospike-rt/rt-async-std"]

[dev-dependencies]
env_logger = "0.7"
hex = "0.4"
bencher = "0.1"
serde_json = "1.0"
aerospike = {path = "../"}
131 changes: 131 additions & 0 deletions aerospike-core/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# Aerospike Rust Client [![crates-io][crates-io-image]][crates-io-url] [![docs][docs-image]][docs-url] [![travis][travis-image]][travis-url] [![appveyor][appveyor-image]][appveyor-url]

[crates-io-image]: https://img.shields.io/crates/v/aerospike.svg
[crates-io-url]: https://crates.io/crates/aerospike
[docs-image]: https://docs.rs/aerospike/badge.svg
[docs-url]: https://docs.rs/aerospike/
[travis-image]: https://travis-ci.org/aerospike/aerospike-client-rust.svg?branch=master
[travis-url]: https://travis-ci.org/aerospike/aerospike-client-rust
[appveyor-image]: https://ci.appveyor.com/api/projects/status/e9gx1b5d1307hj2t/branch/master?svg=true
[appveyor-url]: https://ci.appveyor.com/project/aerospike/aerospike-client-rust/branch/master

An [Aerospike](https://www.aerospike.com/) client library for Rust.

This library is compatible with Rust 1.46+ and supports the following operating systems: Linux, Mac OS X, and Windows.

- [Usage](#Usage)
- [Known Limitations](#Limitations)
- [Tests](#Tests)
- [Benchmarks](#Benchmarks)

<a name="Usage"></a>
## Usage:

The following is a very simple example of CRUD operations in an Aerospike database.

```rust
#[macro_use]
extern crate aerospike;

use std::env;
use std::time::Instant;

use aerospike::{Bins, Client, ClientPolicy, ReadPolicy, WritePolicy};
use aerospike::operations;

fn main() {
let cpolicy = ClientPolicy::default();
let hosts = env::var("AEROSPIKE_HOSTS")
.unwrap_or(String::from("127.0.0.1:3000"));
let client = Client::new(&cpolicy, &hosts)
.expect("Failed to connect to cluster");

let now = Instant::now();
let rpolicy = ReadPolicy::default();
let wpolicy = WritePolicy::default();
let key = as_key!("test", "test", "test");

let bins = [
as_bin!("int", 999),
as_bin!("str", "Hello, World!"),
];
client.put(&wpolicy, &key, &bins).unwrap();
let rec = client.get(&rpolicy, &key, Bins::All);
println!("Record: {}", rec.unwrap());

client.touch(&wpolicy, &key).unwrap();
let rec = client.get(&rpolicy, &key, Bins::All);
println!("Record: {}", rec.unwrap());

let rec = client.get(&rpolicy, &key, Bins::None);
println!("Record Header: {}", rec.unwrap());

let exists = client.exists(&wpolicy, &key).unwrap();
println!("exists: {}", exists);

let bin = as_bin!("int", "123");
let ops = &vec![operations::put(&bin), operations::get()];
let op_rec = client.operate(&wpolicy, &key, ops);
println!("operate: {}", op_rec.unwrap());

let existed = client.delete(&wpolicy, &key).unwrap();
println!("existed (should be true): {}", existed);

let existed = client.delete(&wpolicy, &key).unwrap();
println!("existed (should be false): {}", existed);

println!("total time: {:?}", now.elapsed());
}
```

<a name="Limitations"></a>
## Known Limitations

The following features are not yet supported in the Aerospike Rust client:

- Query Aggregation using Lua User-Defined Functions (UDF).
- Secure connections using TLS.
- IPv6 support.

<a name="Tests"></a>
## Tests

This library is packaged with a number of tests. The tests assume that an
Aerospike cluster is running at `localhost:3000`. To test using a cluster at a
different address, set the `AEROSPIKE_HOSTS` environment variable to the list
of cluster hosts.

To run all the test cases:

```shell
$ export AEROSPIKE_HOSTS=127.0.0.1:3000
$ cargo test
```

To enable debug logging for the `aerospike` crate:

```shell
$ RUST_LOG=aerospike=debug cargo test
```

To enable backtraces set the `RUST_BACKTRACE` environment variable:

```shell
$ RUST_BACKTRACE=1 cargo test
```

<a name="Benchmarks"></a>
## Benchmarks

The micro-benchmarks in the `benches` directory use the
[`bencher`](https://crates.io/crates/bencher) crate and can be run on Rust
stable releases:

```shell
$ export AEROSPIKE_HOSTS=127.0.0.1:3000
$ cargo bench
```

There is a separate benchmark tool under the
[tools/benchmark](tools/benchmark) directory that is designed to
insert data into an Aerospike server cluster and generate load.
Loading