Skip to content

Commit aa84fce

Browse files
authored
Merge pull request #1306 from joshunrau/toxic-proxy
add toxic-proxy.sh and docs
2 parents c2d04cb + 1a03e01 commit aa84fce

File tree

3 files changed

+113
-0
lines changed

3 files changed

+113
-0
lines changed

.env.template

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ LOGIN_REQUEST_THROTTLER_TTL=
7373

7474
# The port to use for the NestJS development server
7575
API_DEV_SERVER_PORT=5500
76+
# The port where the toxic-proxy.sh script should run on
77+
API_DEV_TOXIC_PROXY_PORT=
7678
# The port to use for the Astro (outreach website) development server
7779
OUTREACH_DEV_SERVER_PORT=4000
7880
# The port for the playground
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
---
2+
title: Simulate Poor Network Conditions
3+
slug: en/docs/tutorials/simulate-poor-network
4+
sidebar:
5+
order: 4
6+
---
7+
8+
This guide explains how to use the staged toxic proxy setup to simulate poor network conditions when developing Open Data Capture.
9+
10+
When you run `scripts/toxic-proxy.sh`, it configures Toxiproxy with the following simulated network conditions:
11+
12+
- **Downstream bandwidth limit (API → browser):** capped at **5,000 bytes/second** (~5 KB/s).
13+
- **Upstream bandwidth limit (browser → API):** capped at **2,500 bytes/second** (~2.5 KB/s).
14+
- **Intermittent latency and jitter (downstream):**
15+
- Base latency of **50 ms**, plus up to **500 ms of jitter**.
16+
- Applied with **20% toxicity**, meaning only about 1 in 5 downstream requests/responses are delayed in this way.
17+
- **Occasional random connection resets (downstream):**
18+
- Connections are **randomly reset/closed** from the proxy side.
19+
- Applied with **10% toxicity**, so roughly 1 in 10 downstream connections will be abruptly terminated.
20+
21+
Together, these toxics approximate a slow, unstable network where responses arrive slowly, some requests suffer extra delay, and a minority of connections fail unexpectedly.
22+
23+
### Prerequisites
24+
25+
- Install Toxiproxy (both `toxiproxy-server` and `toxiproxy-cli`) and ensure they are available on your `PATH`.
26+
27+
### Steps
28+
29+
<Steps>
30+
31+
1. **Set the toxic proxy port in `.env`**
32+
33+
Choose a port for the toxic proxy (for example `5501`) and set:
34+
- `API_DEV_TOXIC_PROXY_PORT=5501`
35+
36+
2. **Point the frontend at the toxic proxy**
37+
38+
Update `API_BASE_URL` to use the same port on localhost:
39+
- `API_BASE_URL=http://localhost:5501`
40+
41+
3. **Start the toxic proxy**
42+
43+
Run:
44+
45+
```bash
46+
scripts/toxic-proxy.sh
47+
```
48+
49+
Leave this running. It creates a proxy that sits between the frontend and the API server and applies bandwidth limits.
50+
51+
4. **Launch the app as normal**
52+
53+
In another terminal, run:
54+
55+
```bash
56+
pnpm dev
57+
```
58+
59+
</Steps>
60+
61+
### Notes
62+
63+
- The proxy reads `API_DEV_SERVER_PORT` from `.env` to know where your API server is listening.
64+
- If `API_DEV_TOXIC_PROXY_PORT` is empty, the script exits without starting the proxy.

scripts/toxic-proxy.sh

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
IFS=$'\n\t'
5+
6+
[ "${BASH_VERSINFO:-0}" -ge 5 ] || (echo "Error: Bash >= 5.0 is required for this script" >&2 && exit 1)
7+
8+
PROJECT_ROOT="$(dirname -- "$(dirname -- "$(readlink -f "$0")")")"
9+
10+
source "${PROJECT_ROOT}/.env"
11+
12+
API_DEV_SERVER_PORT="${API_DEV_SERVER_PORT:-}"
13+
API_DEV_TOXIC_PROXY_PORT="${API_DEV_TOXIC_PROXY_PORT:-}"
14+
15+
if [[ -z "$API_DEV_SERVER_PORT" ]]; then
16+
echo "Error: API_DEV_SERVER_PORT is not set" >&2
17+
exit 1
18+
fi
19+
20+
if [ -z "$API_DEV_TOXIC_PROXY_PORT" ]; then
21+
exit 0
22+
fi
23+
24+
cleanup() {
25+
echo "Shutting down..."
26+
kill "$TOXIPROXY_PID" 2>/dev/null || true
27+
wait "$TOXIPROXY_PID" 2>/dev/null || true
28+
}
29+
30+
trap cleanup EXIT
31+
32+
toxiproxy-server &
33+
TOXIPROXY_PID=$!
34+
sleep 1
35+
36+
toxiproxy-cli create --listen "0.0.0.0:$API_DEV_TOXIC_PROXY_PORT" --upstream "127.0.0.1:$API_DEV_SERVER_PORT" odc-api
37+
38+
toxiproxy-cli toxic add -n downstream-bandwidth -t bandwidth -a rate=5000 -a type=downstream odc-api
39+
40+
toxiproxy-cli toxic add -n upstream-bandwidth -t bandwidth -a rate=2500 -a type=upstream odc-api
41+
42+
toxiproxy-cli toxic add -n latency -t latency -a latency=50 -a jitter=500 -a type=downstream -toxicity 0.2 odc-api
43+
44+
toxiproxy-cli toxic add -n random-resets -t reset_peer -a type=tox_type=downstream -toxicity 0.1 odc-api
45+
46+
wait "$TOXIPROXY_PID"
47+

0 commit comments

Comments
 (0)