Skip to content

Commit 0540fe9

Browse files
committed
sentry benchmark:
- docker-compose.harness.yml - add sentry release services - sentry - bin - seed - the sentry - primitives - test_util - add testing Campaigns - sentry - Makefile - add tasks for running the benchmark - sentry - benchmark - multiple_benchmark with 3 campaigns - Docker-sentry - fixes and changes for release build - sentry - README - document how to run benchmarks - scripts - sentry-docker - entrypoint - fixes to hosts & default values
1 parent 2bbdc1e commit 0540fe9

File tree

11 files changed

+250
-16
lines changed

11 files changed

+250
-16
lines changed

Dockerfile-sentry

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,21 @@ WORKDIR /usr/src/app
1010
RUN mkdir -p primitives/src/ adapter/src/ sentry/src/
1111

1212
COPY ./primitives/Cargo.toml ./primitives/Cargo.toml
13+
# we also need to copy the examples otherwise we will get error for them
14+
COPY ./primitives/examples ./primitives/examples
1315
RUN touch ./primitives/src/lib.rs && echo "pub fn main() {println!(\"cargo:rerun-if-changed=\\\"/tmp/build.rs\\\"\");}" >> ./primitives/src/lib.rs
1416

1517
COPY ./adapter/Cargo.toml ./adapter/Cargo.toml
1618
RUN touch ./adapter/src/lib.rs && echo "pub fn main() {println!(\"cargo:rerun-if-changed=\\\"/tmp/build.rs\\\"\");}" >> ./adapter/src/lib.rs
1719

1820
COPY ./sentry/Cargo.toml ./sentry/Cargo.toml
21+
COPY ./sentry/src/bin ./sentry/src/bin
1922
RUN touch ./sentry/src/main.rs && echo "fn main() {println!(\"cargo:rerun-if-changed=\\\"/tmp/build.rs\\\"\");}" >> ./sentry/src/main.rs
2023

2124
COPY ./Cargo.lock ./Cargo.lock
2225
RUN touch Cargo.toml && echo "[workspace]\n members = [ 'primitives', 'adapter', 'sentry' ]" >> Cargo.toml
2326

24-
RUN cargo build -p sentry --release
27+
RUN cargo build -p sentry --bin sentry --release
2528

2629
# remove the not needed build artifacts
2730
RUN rm -f target/release/deps/sentry*
@@ -35,7 +38,7 @@ COPY . .
3538
# We install the sentry binary with all features in Release mode
3639
# Include the full backtrace for easier debugging
3740

38-
RUN RUST_BACKTRACE=full cargo install --locked --path sentry --all-features
41+
RUN RUST_BACKTRACE=full cargo install --locked --path sentry --bin sentry --all-features
3942

4043
WORKDIR /usr/local/bin
4144

@@ -79,13 +82,11 @@ COPY docs/config/cloudflare_origin.crt /usr/local/share/ca-certificates/
7982

8083
RUN update-ca-certificates
8184

82-
RUN mkdir scripts
83-
84-
COPY ./scripts/sentry-docker ./scripts
85+
COPY ./scripts/sentry-docker ./scripts/sentry-docker
8586

8687
COPY --from=builder /usr/local/bin/sentry .
8788

88-
ENTRYPOINT ["./scripts/entrypoint.sh"]
89+
ENTRYPOINT ["./scripts/sentry-docker/entrypoint.sh"]
8990

9091
CMD sentry -a ${ADAPTER:-ethereum} \
9192
${KEYSTORE_FILE:+-k $KEYSTORE_FILE} \

docker-compose.harness.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,28 @@ services:
5858
networks:
5959
- adex-external
6060

61+
# Service used to bechmark the sentry application in release mode
62+
# It uses the dummy adapter and the Leader
63+
sentry-dummy-leader-release:
64+
restart: unless-stopped
65+
build:
66+
context: .
67+
dockerfile: Dockerfile-sentry
68+
container_name: adex-sentry-dummy-leader-release
69+
ports:
70+
- "8005:8005"
71+
environment:
72+
ENV: development
73+
IP_ADDR: 0.0.0.0
74+
PORT: 8005
75+
POSTGRES_DB: sentry_leader
76+
POSTGRES_HOST: adex-postgres
77+
REDIS_HOST: adex-redis
78+
ADAPTER: dummy
79+
DUMMY_IDENTITY: '0x80690751969B234697e9059e04ed72195c3507fa'
80+
REDIS_URL: redis://adex-redis:6379/0
81+
networks:
82+
- adex-external
83+
6184
networks:
6285
adex-external:

scripts/sentry-docker/entrypoint.sh

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ set -o errexit
44
set -o pipefail
55

66
>&2 echo "Waiting for redis..."
7-
REDIS_HOST=${REDIS_HOST:-redis}
7+
REDIS_HOST=${REDIS_HOST:-localhost}
88
REDIS_PORT=${REDIS_PORT:-6379}
9-
./scripts/wait-for-it.sh -h ${REDIS_HOST} -p ${REDIS_PORT} -t 10
9+
./scripts/sentry-docker/wait-for-it.sh -h ${REDIS_HOST} -p ${REDIS_PORT} -t 10
1010
>&2 echo "Redis is up - continuing..."
1111

1212
>&2 echo "Waiting for postgres..."
13-
POSTGRES_HOST=${POSTGRES_HOST:-postgres}
13+
POSTGRES_HOST=${POSTGRES_HOST:-localhost}
1414
POSTGRES_PORT=${POSTGRES_PORT:-5432}
15-
./scripts/wait-for-it.sh -h ${POSTGRES_HOST} -p ${POSTGRES_PORT} -t 10
15+
./scripts/sentry-docker/wait-for-it.sh -h ${POSTGRES_HOST} -p ${POSTGRES_PORT} -t 10
1616
>&2 echo "Postgres is up - continuing..."
1717

1818
exec "$@"

sentry/Cargo.toml

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@ authors = [
99
]
1010
edition = "2021"
1111

12+
default-run = "sentry"
13+
14+
[[bin]]
15+
name = "seed"
16+
test = false # Is tested by default.
17+
doctest = false # Documentation examples are tested by default.
18+
bench = false # Is benchmarked by default.
19+
doc = false # Is documented by default.
20+
required-features = ["test-util"]
21+
1222
[features]
1323

1424
test-util = ["primitives/test-util", "adapter/test-util", "dashmap"]
@@ -18,8 +28,8 @@ test-util = ["primitives/test-util", "adapter/test-util", "dashmap"]
1828
futures = "0.3"
1929
async-trait = "0.1"
2030
# Primitives
21-
primitives = { path = "../primitives", features = ["postgres", "test-util"] }
22-
adapter = { version = "0.2", path = "../adapter", features = ["test-util"] }
31+
primitives = { path = "../primitives", features = ["postgres"] }
32+
adapter = { version = "0.2", path = "../adapter" }
2333
chrono = { version = "0.4", features = ["serde"] }
2434
# used for redis test pool
2535
dashmap = { version = "5", optional = true }
@@ -65,6 +75,9 @@ reqwest = { version = "0.11", features = ["json", "cookies"] }
6575
[dev-dependencies]
6676
pretty_assertions = "1"
6777

78+
primitives = { path = "../primitives", features = ["postgres", "test-util"] }
79+
adapter = { version = "0.2", path = "../adapter", features = ["test-util"] }
80+
6881
[package.metadata.docs.rs]
6982
all-features = true
7083
rustdoc-args = ["--cfg", "docsrs"]

sentry/Makefile.toml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,43 @@ script = "docker-compose -f ../docker-compose.harness.yml up -d adex-redis adex-
2323

2424
[tasks.services-down]
2525
script = "docker-compose -f ../docker-compose.harness.yml down"
26+
27+
[tasks.run-benchmark]
28+
category = "Development"
29+
30+
dependencies = [
31+
"benchmark-services-up",
32+
"run-seed",
33+
"run-wrk2",
34+
"benchmark-services-down",
35+
]
36+
37+
[tasks.run-seed]
38+
category = "Development"
39+
40+
command = "cargo"
41+
42+
args = ["run", "--bin", "seed", "--features=test-util"]
43+
44+
[tasks.run-wrk2]
45+
category = "Development"
46+
47+
command = "wrk2"
48+
49+
args = [
50+
"-s",
51+
"./benchmark/multiple_benchmark.lua",
52+
"-t3",
53+
"-c100",
54+
"-d30s",
55+
"-R2000",
56+
"--latency",
57+
"http://127.0.0.1:8005/v5/campaign",
58+
]
59+
60+
[tasks.benchmark-services-up]
61+
# `--renew-anon-volumes` is required to make sure that the Databases are dumpped.
62+
script = "docker-compose -f ../docker-compose.harness.yml up --renew-anon-volumes -d adex-redis adex-postgres sentry-dummy-leader-release && sleep 3"
63+
64+
[tasks.benchmark-services-down]
65+
script = "docker-compose -f ../docker-compose.harness.yml down"

sentry/README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,13 @@ to create them for you.
2424
2) And setup the `Migrant.toml` file, a reference to which you can find
2525
in [Migrant.dist.toml](Migrant.dist.toml).
2626

27-
For more options see the [migrant homepage](https://github.com/jaemk/migrant)
27+
For more options see the [migrant homepage](https://github.com/jaemk/migrant)
28+
29+
#### Benchmarks
30+
31+
Starts the `Sentry` application along side `redis` and `postgres` databases,
32+
and runs `wrk2` on the POST `/v5/campaign/0xXXXX../events` route for 3 campaigns:
33+
34+
```bash
35+
cargo make run-benchmark
36+
```

sentry/benchmark/benchmark.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env bash
22

33
# Run the benchmark using
4-
# t3 - one thread
4+
# t3 - three threads
55
# c100 - one hundred concurrent connections
66
# d30s - 30 seconds
77
# R2000 - 2000 requests per second (total, across all connections combined)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
-- This script will submit events for 3 campaigns
2+
-- The 3 campaigns can be found in `primitives::test_util`
3+
wrk.method = "POST"
4+
-- uses the PUBLISHER address
5+
wrk.body = "{ \"events\": [ {\"type\": \"IMPRESSION\", \"publisher\": \"0xE882ebF439207a70dDcCb39E13CA8506c9F45fD9\", \"adUnit\": \"Qmasg8FrbuSQpjFu3kRnZF9beg8rEBFrqgi1uXDRwCbX5f\", \"adSlot\": \"QmcUVX7fvoLMM93uN2bD3wGTH8MXSxeL8hojYfL2Lhp7mR\"} ] }"
6+
wrk.headers["Content-Type"] = "application/json"
7+
-- uses the DUMMY_AUTH[CREATOR] token
8+
-- wrk.headers["authorization"] = "Bearer AUTH_awesomeCreator:chain_id:1337"
9+
10+
11+
init = function(args)
12+
local r = {}
13+
14+
-- Campaign 1
15+
r[1] = wrk.format(nil, "/v5/campaign/0x936da01f9abd4d9d80c702af85c822a8/events")
16+
-- Campaign 2
17+
r[2] = wrk.format(nil, "/v5/campaign/0x127b98248f4e4b73af409d10f62daeaa/events")
18+
-- Campaign 3
19+
r[3] = wrk.format(nil, "/v5/campaign/0xa78f3492481b41a688488a7aa1ff17df/events")
20+
21+
req = table.concat(r)
22+
end
23+
24+
request = function()
25+
return req
26+
end

sentry/src/bin/seed.rs

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
use adapter::{client::Unlocked, dummy::Options, Adapter, Dummy, UnlockedState};
2+
use primitives::{
3+
config::GANACHE_CONFIG,
4+
sentry::SuccessResponse,
5+
test_util::{ADVERTISER, ADVERTISER_2, CAMPAIGNS, DUMMY_AUTH, IDS, LEADER},
6+
unified_num::FromWhole,
7+
util::ApiUrl,
8+
Campaign, ChainOf, Channel, Deposit, UnifiedNum, ValidatorId,
9+
};
10+
use reqwest::Client;
11+
use sentry::routes::channel::ChannelDummyDeposit;
12+
13+
#[tokio::main]
14+
async fn main() -> Result<(), Box<dyn std::error::Error>> {
15+
let advertiser_adapter = Adapter::with_unlocked(Dummy::init(Options {
16+
dummy_identity: IDS[&ADVERTISER],
17+
dummy_auth_tokens: DUMMY_AUTH.clone(),
18+
dummy_chains: GANACHE_CONFIG.chains.values().cloned().collect(),
19+
}));
20+
21+
let advertiser2_adapter = Adapter::with_unlocked(Dummy::init(Options {
22+
dummy_identity: IDS[&ADVERTISER_2],
23+
dummy_auth_tokens: DUMMY_AUTH.clone(),
24+
dummy_chains: GANACHE_CONFIG.chains.values().cloned().collect(),
25+
}));
26+
27+
let client = reqwest::Client::new();
28+
// add deposit for campaigns
29+
let intended_for = (
30+
"http://127.0.0.1:8005".parse::<ApiUrl>().unwrap(),
31+
IDS[&LEADER],
32+
);
33+
34+
// create campaign
35+
// Chain 1337
36+
let campaign_1 = CAMPAIGNS[0].clone();
37+
// Chain 1337
38+
let campaign_2 = CAMPAIGNS[1].clone();
39+
// Chain 1
40+
let campaign_3 = CAMPAIGNS[2].clone();
41+
// chain 1337
42+
dummy_deposit(
43+
&client,
44+
&advertiser_adapter,
45+
&campaign_1.of_channel(),
46+
&intended_for,
47+
)
48+
.await?;
49+
// chain 1337
50+
dummy_deposit(
51+
&client,
52+
&advertiser_adapter,
53+
&campaign_2.of_channel(),
54+
&intended_for,
55+
)
56+
.await?;
57+
// chain 1
58+
dummy_deposit(
59+
&client,
60+
&advertiser2_adapter,
61+
&campaign_3.of_channel(),
62+
&intended_for,
63+
)
64+
.await?;
65+
66+
create_campaign(&client, &advertiser_adapter, &campaign_1, &intended_for).await?;
67+
create_campaign(&client, &advertiser_adapter, &campaign_2, &intended_for).await?;
68+
create_campaign(&client, &advertiser2_adapter, &campaign_3, &intended_for).await?;
69+
70+
Ok(())
71+
}
72+
73+
async fn create_campaign(
74+
client: &Client,
75+
adapter: &Adapter<Dummy, UnlockedState>,
76+
campaign: &ChainOf<Campaign>,
77+
(sentry_url, intended_for): &(ApiUrl, ValidatorId),
78+
) -> Result<(), Box<dyn std::error::Error>> {
79+
let auth_token = adapter.get_auth(campaign.chain.chain_id, *intended_for)?;
80+
81+
let _result = client
82+
.post(sentry_url.join("/v5/campaign")?)
83+
.bearer_auth(auth_token)
84+
.json(&campaign.context)
85+
.send()
86+
.await?
87+
.error_for_status()?
88+
.json::<Campaign>()
89+
.await?;
90+
91+
Ok(())
92+
}
93+
94+
async fn dummy_deposit(
95+
client: &Client,
96+
adapter: &Adapter<Dummy, UnlockedState>,
97+
channel: &ChainOf<Channel>,
98+
(sentry_url, for_validator): &(ApiUrl, ValidatorId),
99+
) -> Result<(), Box<dyn std::error::Error>> {
100+
let auth_token = adapter.get_auth(channel.chain.chain_id, *for_validator)?;
101+
102+
let request = ChannelDummyDeposit {
103+
channel: channel.context,
104+
deposit: Deposit {
105+
total: UnifiedNum::from_whole(1_000_000),
106+
},
107+
};
108+
109+
let result = client
110+
.post(sentry_url.join("/v5/channel/dummy-deposit")?)
111+
.bearer_auth(auth_token)
112+
.json(&request)
113+
.send()
114+
.await?
115+
.error_for_status()?
116+
.json::<SuccessResponse>()
117+
.await?;
118+
119+
assert!(result.success);
120+
121+
Ok(())
122+
}

sentry/src/db/accounting.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use primitives::{
55
};
66
use tokio_postgres::{
77
types::{FromSql, ToSql},
8-
IsolationLevel, Row,
8+
Row,
99
};
1010

1111
use super::{DbPool, PoolError};

0 commit comments

Comments
 (0)