Skip to content

Conversation

@chakra-guy
Copy link
Collaborator

Summary

Adds three high-fidelity load testing scenarios for SLO validation using actual protocol clients (DappClient, WalletClient). These scenarios test the relay server from the application's perspective, not just raw WebSocket connections.

New Scenarios

Scenario Purpose Key Metrics
realistic-session Full dApp+Wallet handshake with message exchange Handshake latency, message RTT
async-delivery Historical message recovery after wallet disconnect/reconnect Recovery latency, delivery rate
steady-messaging Sustained message latency under load over time P99 latency trend, connection stability

Implementation Details

High-Fidelity Design

  • Uses actual DappClient and WalletClient from protocol libraries
  • Trusted mode connection flow (no OTP)
  • Realistic timing: 5s wallet connect delay (simulates QR scan), 1s message delay

Performance Optimizations

  • MockKeyManager: Bypasses real ECIES crypto (CPU-intensive) since the relay only sees opaque payloads
  • Reusable runWithPacing() utility for consistent ramp-up behavior across scenarios

New Files

  • client/session-pair.ts - Session pair creation and messaging
  • client/key-manager.ts - Mock crypto for load testing
  • utils/pacing.ts - Pacing utilities
  • utils/kvstore.ts - In-memory KV store
  • scenarios/realistic-session.ts, async-delivery.ts, steady-messaging.ts

Usage

Realistic session: handshake + message exchange

yarn start --scenario=realistic-session --target=ws://... --connections=100 --ramp-up=10 --messages-per-session=3

Async delivery: historical message recovery

yarn start --scenario=async-delivery --target=ws://... --connections=100 --ramp-up=10 --delay=30

Steady messaging: sustained load over time

yarn start --scenario=steady-messaging --target=ws://... --connections=100 --ramp-up=10 --duration=120 --message-interval=5

@chakra-guy chakra-guy force-pushed the ts/setup-load-testing branch from 59062fd to f75e1ab Compare January 15, 2026 09:25
…testing

- DigitalOcean droplet provisioning (create/destroy)
- SSH-based command execution on droplets
- Parallel execution with progress tracking
- Results collection via SFTP
- Background execution for long-running tests
- Results aggregation across multiple droplets
- Fix latency aggregation bug (allLatencies was never populated)
- Rename latency → connectTime to match scaffolding PR
- Use corepack for Yarn installation instead of npm install -g yarn
- Fix SSH exit code null handling (assume failure if no exit code)
- Add concurrency limit (5) for droplet creation to avoid rate limits
- Add aggregator input validation for required fields
- Extract DROPLET_HOURLY_COST constant
- Add branch name validation to prevent shell injection (droplet.ts, infra.ts)
- Add regex escaping for name prefix to prevent incorrect droplet matching
- Add shell single-quote escaping for file paths in wait command
- Add NaN validation for timeout/interval to prevent infinite loops
- Add timeout to SFTP download to prevent hanging indefinitely
@chakra-guy chakra-guy force-pushed the ts/setup-load-testing branch from f75e1ab to fa791da Compare January 15, 2026 09:37
Add three new scenarios for SLO validation using actual protocol clients:

- realistic-session: Full dApp+Wallet handshake with message exchange
- async-delivery: Tests historical message recovery after wallet reconnect
- steady-messaging: Sustained message latency under load over time

Key implementation details:
- Uses MockKeyManager for lightweight crypto (CPU-efficient load generation)
- Realistic timing: 5s wallet connect delay, 1s message delay
- Reusable pacing utility (runWithPacing) for all scenarios
- InMemoryKVStore for session management

All scenarios verified against local Docker Compose with 100% success rates.
Base automatically changed from ts/setup-load-testing to main January 15, 2026 10:09
… waits before responding (simulates user reviewing request) - Each round: dApp sends → wallet waits → wallet responds → dApp receives - Response delay = message interval (e.g., 10s) - Latency measured excludes artificial delay (actual network time only) - Rounds run sequentially, no overlapping
Key changes:
- Each pair starts its messaging loop immediately upon connecting
- No synchronized bursts - load is naturally distributed
- Both sides wait: dApp sends → wallet waits → responds → dApp waits → repeat
- Message cycle takes 2 * messageInterval (e.g., 20s for 10s interval)
- Pairs connect during ramp-up and start messaging right away
- Metrics collected continuously with periodic snapshots
…tions

The protocol needs time to synchronize internal state before message
exchange can reliably work. 100ms was insufficient for production
connections with ~200ms latency. 500ms provides a reliable buffer.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants