Skip to content

Commit a737694

Browse files
hlbarbercrisidev
andauthored
Move examples to root, refactor to workspace, and refactor integration tests (#2481)
* Move examples * Update documentation * Add to CI * Fix CI * Cleanup * Fix clippy lints * Fix documentation * Bump example dependencies * Cleanup * Update documentation --------- Co-authored-by: Matteo Bigoi <1781140+crisidev@users.noreply.github.com>
1 parent f3e4474 commit a737694

File tree

36 files changed

+673
-554
lines changed

36 files changed

+673
-554
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ Project Layout
3838
* [`design`](design): Design documentation. See the [design/README.md](design/README.md) for details about building / viewing.
3939
* `codegen-server`: Whitelabel Smithy server code generation
4040
* `codegen-server-test`: Smithy protocol test generation & integration tests for Smithy server whitelabel code
41+
* `examples`: A collection of server implementation examples
4142

4243
Testing
4344
-------

design/src/server/anatomy.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,7 @@ stateDiagram-v2
648648
Op1 --> Op2 : Plugin#colon;#colon;map
649649
```
650650

651-
An example `Plugin` implementation can be found in [aws-smithy-http-server/examples/pokemon-service/src/plugin.rs](https://github.com/awslabs/smithy-rs/blob/main/rust-runtime/aws-smithy-http-server/examples/pokemon-service/src/plugin.rs).
651+
An example `Plugin` implementation can be found in [/examples/pokemon-service/src/plugin.rs](https://github.com/awslabs/smithy-rs/blob/main/examples/pokemon-service/src/plugin.rs).
652652

653653
The service builder API requires plugins to be specified upfront - they must be passed as an argument to `builder_with_plugins` and cannot be modified afterwards.
654654
This constraint is in place to ensure that all handlers are upgraded using the same set of plugins.

design/src/server/instrumentation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ let app = PokemonService::builder_with_plugins(plugins)
6969

7070
### Example
7171

72-
The Pokémon service example, located at `rust-runtime/aws-smithy-http-server/examples/pokemon-service`, sets up a `tracing` `Subscriber` as follows:
72+
The Pokémon service example, located at `/examples/pokemon-service`, sets up a `tracing` `Subscriber` as follows:
7373

7474
```rust
7575
/// Setup `tracing::subscriber` to read the log level from RUST_LOG environment variable.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
pokemon-service-client/
22
pokemon-service-server-sdk/
3+
Cargo.lock

rust-runtime/aws-smithy-http-server/examples/BENCHMARKS.md renamed to examples/BENCHMARKS.md

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ using [wrk](https://github.com/wg/wrk).
55

66
<!-- vim-markdown-toc Marked -->
77

8-
* [2022-03-04](#2022-03-04)
9-
* [c6i.8xlarge](#c6i.8xlarge)
10-
* [Full result](#full-result)
11-
* [c6g.8xlarge](#c6g.8xlarge)
12-
* [Full result](#full-result)
8+
- [Smithy Rust Server SDK benchmarks](#smithy-rust-server-sdk-benchmarks)
9+
- [2022-03-04](#2022-03-04)
10+
- [c6i.8xlarge](#c6i8xlarge)
11+
- [Full result](#full-result)
12+
- [c6g.8xlarge](#c6g8xlarge)
13+
- [Full result](#full-result-1)
1314

1415
<!-- vim-markdown-toc -->
1516

@@ -20,19 +21,19 @@ returning an empty output and can be used to stress test the framework overhead.
2021

2122
### c6i.8xlarge
2223

23-
* 32 cores Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz
24-
* 64 Gb memory
25-
* Benchmark:
26-
- Duration: 10 minutes
27-
- Connections: 1024
28-
- Threads: 16
29-
* Result:
30-
- Request/sec: 1_608_742
31-
* RSS[^1] memory: 72200 bytes
24+
- 32 cores Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz
25+
- 64 Gb memory
26+
- Benchmark:
27+
- Duration: 10 minutes
28+
- Connections: 1024
29+
- Threads: 16
30+
- Result:
31+
- Request/sec: 1_608_742
32+
- RSS[^1] memory: 72200 bytes
3233

3334
#### Full result
3435

35-
```
36+
```text
3637
❯❯❯ wrk -t16 -c1024 -d10m --latency http://localhost:13734/empty-operation
3738
Running 10m test @ http://localhost:13734/empty-operation
3839
16 threads and 1024 connections
@@ -52,20 +53,20 @@ Transfer/sec: 167.23MB
5253

5354
### c6g.8xlarge
5455

55-
* 32 cores Amazon Graviton 2 @ 2.50GHz
56-
* 64 Gb memory
57-
* Benchmark:
58-
- Duration: 10 minutes
59-
- Connections: 1024
60-
- Threads: 16
61-
* Result:
62-
- Request/sec: 1_379_942
63-
- RSS[^1] memory: 70264 bytes
56+
- 32 cores Amazon Graviton 2 @ 2.50GHz
57+
- 64 Gb memory
58+
- Benchmark:
59+
- Duration: 10 minutes
60+
- Connections: 1024
61+
- Threads: 16
62+
- Result:
63+
- Request/sec: 1_379_942
64+
- RSS[^1] memory: 70264 bytes
6465

6566

6667
#### Full result
6768

68-
```
69+
```text
6970
❯❯❯ wrk -t16 -c1024 -d10m --latency http://localhost:13734/empty-operation
7071
Running 10m test @ http://localhost:13734/empty-operation
7172
16 threads and 1024 connections

rust-runtime/aws-smithy-http-server/examples/Cargo.toml renamed to examples/Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
# Without this configuration, the workspace will be read from `rust-runtime`, causing the build to fail.
22
[workspace]
33
members = [
4+
"pokemon-service-common",
45
"pokemon-service",
6+
"pokemon-service-tls",
7+
"pokemon-service-lambda",
58
"pokemon-service-server-sdk",
6-
"pokemon-service-client",
9+
"pokemon-service-client"
710
]
811

912
[profile.release]

examples/README.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# Smithy Rust Server SDK examples
2+
3+
This folder contains an example services showcasing the service framework capabilities and to run benchmarks.
4+
5+
- `/pokemon-service`, a HTTP server implementation demonstrating [middleware](https://awslabs.github.io/smithy-rs/design/server/middleware.html)
6+
and [extractors](https://awslabs.github.io/smithy-rs/design/server/from_parts.html).
7+
- `/pokemon-service-tls`, a minimal HTTPS server implementation.
8+
- `/pokemon-service-lambda`, a minimal Lambda deployment.
9+
10+
The `/{binary}/tests` folders are integration tests involving the generated clients.
11+
12+
## Build
13+
14+
Since this example requires both the server and client SDK to be code-generated
15+
from their [model](/codegen-server-test/model/pokemon.smithy), a Makefile is
16+
provided to build and run the service. Just run `make` to prepare the first
17+
build.
18+
19+
Once the example has been built successfully the first time, idiomatic `cargo`
20+
can be used directly.
21+
22+
`make distclean` can be used for a complete cleanup of all artefacts.
23+
24+
## Run
25+
26+
To run a binary use
27+
28+
```bash
29+
cargo run -p $BINARY
30+
```
31+
32+
CLI arguments can be passed to the servers, use
33+
34+
```bash
35+
cargo run -p $BINARY -- --help
36+
```
37+
38+
for more information.
39+
40+
## Test
41+
42+
`cargo test` can be used to spawn a service and run some simple integration
43+
tests against it. Use `-p $BINARY` to filter by package.
44+
45+
More info can be found in the `tests` folder of each package.
46+
47+
## Benchmarks
48+
49+
Please see [BENCHMARKS.md](/examples/BENCHMARKS.md).
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
[package]
2+
name = "pokemon-service-common"
3+
version = "0.1.0"
4+
edition = "2021"
5+
publish = false
6+
authors = ["Smithy-rs Server Team <smithy-rs-server@amazon.com>"]
7+
description = "A smithy Rust service to retrieve information about Pokémon."
8+
9+
[dependencies]
10+
async-stream = "0.3"
11+
http = "0.2.9"
12+
rand = "0.8"
13+
tracing = "0.1"
14+
tracing-subscriber = { version = "0.3.16", features = ["env-filter", "json"] }
15+
tokio = { version = "1", default-features = false, features = ["time"] }
16+
17+
# Local paths
18+
aws-smithy-http = { path = "../../rust-runtime/aws-smithy-http" }
19+
aws-smithy-http-server = { path = "../../rust-runtime/aws-smithy-http-server" }
20+
pokemon-service-client = { path = "../pokemon-service-client" }
21+
pokemon-service-server-sdk = { path = "../pokemon-service-server-sdk" }
22+
23+
[dev-dependencies]
24+
tower = "0.4"
Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,19 @@
1010
use std::{
1111
collections::HashMap,
1212
convert::TryInto,
13+
process::Child,
1314
sync::{atomic::AtomicUsize, Arc},
1415
};
1516

1617
use async_stream::stream;
18+
use aws_smithy_http::operation::Request;
1719
use aws_smithy_http_server::Extension;
18-
use pokemon_service_server_sdk::{error, input, model, model::CapturingPayload, output, types::Blob};
20+
use pokemon_service_server_sdk::{
21+
error, input, model, model::CapturingPayload, output, types::Blob,
22+
};
1923
use rand::Rng;
2024
use tracing_subscriber::{prelude::*, EnvFilter};
2125

22-
pub mod plugin;
23-
2426
const PIKACHU_ENGLISH_FLAVOR_TEXT: &str =
2527
"When several of these Pokémon gather, their electricity could build and cause lightning storms.";
2628
const PIKACHU_SPANISH_FLAVOR_TEXT: &str =
@@ -30,13 +32,37 @@ const PIKACHU_ITALIAN_FLAVOR_TEXT: &str =
3032
const PIKACHU_JAPANESE_FLAVOR_TEXT: &str =
3133
"ほっぺたの りょうがわに ちいさい でんきぶくろを もつ。ピンチのときに ほうでんする。";
3234

35+
/// Rewrites the base URL of a request
36+
pub fn rewrite_base_url(base_url: String) -> impl Fn(Request) -> Request + Clone {
37+
move |mut req| {
38+
let http_req = req.http_mut();
39+
let uri = format!("{base_url}{}", http_req.uri().path());
40+
*http_req.uri_mut() = uri.parse().unwrap();
41+
req
42+
}
43+
}
44+
45+
/// Kills [`Child`] process when dropped.
46+
#[derive(Debug)]
47+
#[must_use]
48+
pub struct ChildDrop(pub Child);
49+
50+
impl Drop for ChildDrop {
51+
fn drop(&mut self) {
52+
self.0.kill().expect("failed to kill process")
53+
}
54+
}
55+
3356
/// Setup `tracing::subscriber` to read the log level from RUST_LOG environment variable.
3457
pub fn setup_tracing() {
3558
let format = tracing_subscriber::fmt::layer().json();
3659
let filter = EnvFilter::try_from_default_env()
3760
.or_else(|_| EnvFilter::try_new("info"))
3861
.unwrap();
39-
tracing_subscriber::registry().with(format).with(filter).init();
62+
tracing_subscriber::registry()
63+
.with(format)
64+
.with(filter)
65+
.init();
4066
}
4167

4268
/// Structure holding the translations for a Pokémon description.
@@ -134,7 +160,10 @@ pub async fn get_pokemon_species(
134160
input: input::GetPokemonSpeciesInput,
135161
state: Extension<Arc<State>>,
136162
) -> Result<output::GetPokemonSpeciesOutput, error::GetPokemonSpeciesError> {
137-
state.0.call_count.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
163+
state
164+
.0
165+
.call_count
166+
.fetch_add(1, std::sync::atomic::Ordering::SeqCst);
138167
// We only support retrieving information about Pikachu.
139168
let pokemon = state.0.pokemons_translations.get(&input.name);
140169
match pokemon.as_ref() {
@@ -215,7 +244,9 @@ pub async fn capture_pokemon(
215244
) -> Result<output::CapturePokemonOutput, error::CapturePokemonError> {
216245
if input.region != "Kanto" {
217246
return Err(error::CapturePokemonError::UnsupportedRegionError(
218-
error::UnsupportedRegionError { region: input.region },
247+
error::UnsupportedRegionError {
248+
region: input.region,
249+
},
219250
));
220251
}
221252
let output_stream = stream! {
@@ -307,7 +338,10 @@ mod tests {
307338
.find(|flavor_text| flavor_text.language == model::Language::Spanish)
308339
.unwrap();
309340

310-
assert_eq!(PIKACHU_SPANISH_FLAVOR_TEXT, actual_spanish_flavor_text.flavor_text());
341+
assert_eq!(
342+
PIKACHU_SPANISH_FLAVOR_TEXT,
343+
actual_spanish_flavor_text.flavor_text()
344+
);
311345

312346
let input = input::GetServerStatisticsInput {};
313347
let stats = get_server_statistics(input, Extension(state.clone())).await;

0 commit comments

Comments
 (0)