개발 가이드¶
이 가이드는 Continuum Router 프로젝트의 개발 환경 설정, 아키텍처, 테스트, 기여 방법을 다룹니다.
목차¶
사전 요구 사항¶
필수 도구¶
- Rust: 1.95 이상 (Rust 설치); 루트 라우터 패키지와 독립
perf/하네스는 Rust edition 2024를 사용하고, 저장소는 재현 가능한 CI와 로컬 린트를 위해rust-toolchain.toml에서 Rust 1.97.1을 고정합니다. - Git: 버전 관리용
- C 컴파일러: gcc, clang, 또는 MSVC (네이티브 의존성용)
Rust edition, MSRV, 그리고 포매팅¶
루트 continuum-router 패키지와 독립 perf/ 하네스는 Rust edition 2024와 rust-version = "1.95"를 선언합니다. 벤더링된 crates/continuum-protocol 패키지는 upstream Continuum Hub 프로토콜 크레이트를 반영하므로 의도적으로 edition 2021과 Rust 1.88에 남겨 둡니다. Cargo는 이 혼합 edition 그래프를 지원하며, 라우터 CI는 해당 path dependency를 별도로 검증합니다. rustfmt.toml은 style_edition = "2021"을 고정해 별도 포매팅 전용 마이그레이션이 승인되기 전까지 cargo fmt와 에디터 통합이 기존 포매팅 스타일을 유지하도록 합니다.
권장 도구¶
- cargo-watch: 개발 중 자동 재컴파일
- cargo-edit: 의존성 관리
- cargo-audit: 보안 취약점 검사
- cargo-flamegraph: 성능 프로파일링
- rust-analyzer: IDE 지원 (VS Code, IntelliJ, vim/neovim)
개발 도구 설치¶
# 필수 개발 도구 설치
cargo install cargo-watch cargo-edit cargo-audit cargo-flamegraph
# 코드 커버리지 도구 설치
cargo install cargo-tarpaulin
# 벤치마킹 도구 설치
cargo install cargo-criterion
개발 설정¶
복제 및 설정¶
# 저장소 복제
git clone https://github.com/lablup/continuum-router.git
cd continuum-router
# 컴파일 확인
cargo check
# 초기 테스트 스위트 실행
cargo test
# 개발 버전 빌드
cargo build
IDE 설정¶
VS Code¶
rust-analyzer확장 설치- 디버깅을 위해
CodeLLDB확장 설치 - 제공된
.vscode/settings.json사용:
{
"rust-analyzer.cargo.features": "all",
"rust-analyzer.checkOnSave.command": "clippy",
"editor.formatOnSave": true,
"[rust]": {
"editor.defaultFormatter": "rust-lang.rust-analyzer"
}
}
IntelliJ IDEA / CLion¶
- Rust 플러그인 설치
- 프로젝트 루트 열기
- Preferences → Build → Cargo에서 Cargo 설정 구성
Vim/Neovim¶
- Mason 또는 수동으로
rust-analyzer설치 - LSP 클라이언트 구성 (nvim-lspconfig, coc.nvim 등)
- nvim-lspconfig 설정 예제:
require('lspconfig').rust_analyzer.setup({
settings = {
["rust-analyzer"] = {
cargo = { features = "all" },
checkOnSave = { command = "clippy" }
}
}
})
프로젝트 구조¶
계층 아키텍처¶
프로젝트는 깔끔한 4계층 아키텍처를 따릅니다:
디렉토리 구조¶
src/
├── main.rs # 애플리케이션 진입점 및 CLI
├── lib.rs # 라이브러리 익스포트 및 모듈 선언
│
├── core/ # 핵심 도메인 계층 (외부 의존성 없음)
│ ├── mod.rs # Core 모듈 익스포트
│ ├── models/ # 도메인 모델
│ │ ├── backend.rs # 백엔드 설정 및 상태
│ │ ├── model.rs # LLM 모델 표현
│ │ ├── request.rs # 요청/응답 모델
│ │ └── health.rs # 헬스 체크 모델
│ ├── errors.rs # 오류 타입 및 처리
│ ├── traits.rs # 도메인 트레이트 및 인터페이스
│ ├── retry/ # 재시도 로직 및 정책
│ │ ├── policy.rs # 재시도 정책
│ │ └── backoff.rs # 백오프 전략
│ └── config/ # 설정 모델
│ ├── mod.rs # Config 모듈 익스포트
│ ├── models.rs # 설정 구조체
│ └── validation.rs # 설정 유효성 검사 로직
│
├── services/ # 비즈니스 로직 계층
│ ├── mod.rs # 서비스 레지스트리 및 DI 컨테이너
│ ├── backend_service.rs # 백엔드 관리 및 선택
│ ├── model_service.rs # 모델 집계 및 캐싱
│ ├── proxy_service.rs # 요청 라우팅 및 프록시
│ ├── health_service.rs # 헬스 모니터링
│ └── streaming/ # SSE 스트리밍 지원
│ ├── mod.rs # Streaming 모듈 익스포트
│ ├── parser.rs # SSE 이벤트 파싱
│ └── handler.rs # 스트림 처리 로직
│
├── infrastructure/ # 외부 통합 계층
│ ├── mod.rs # Infrastructure 익스포트
│ ├── backends/ # 백엔드 클라이언트 구현
│ │ ├── mod.rs # 백엔드 트레이트 및 팩토리
│ │ ├── openai.rs # OpenAI 호환 백엔드
│ │ ├── ollama.rs # Ollama 백엔드
│ │ └── vllm.rs # vLLM 백엔드
│ ├── cache/ # 캐싱 구현
│ │ ├── mod.rs # 캐시 트레이트
│ │ ├── lru.rs # LRU 캐시
│ │ └── ttl.rs # TTL 기반 캐시
│ ├── config/ # 설정 로딩
│ │ ├── loader.rs # 설정 파일 로딩
│ │ └── watcher.rs # 핫 리로드 지원
│ └── http_client.rs # 풀링이 있는 HTTP 클라이언트
│
├── http/ # HTTP 계층
│ ├── mod.rs # HTTP 모듈 익스포트
│ ├── routes.rs # 라우트 정의
│ ├── handlers/ # 요청 핸들러
│ │ ├── chat.rs # 채팅 완료 엔드포인트
│ │ ├── models.rs # 모델 목록 엔드포인트
│ │ ├── health.rs # 헬스 체크 엔드포인트
│ │ └── admin.rs # 관리자 엔드포인트
│ ├── middleware/ # HTTP 미들웨어
│ │ ├── auth.rs # 인증
│ │ ├── logging.rs # 요청 로깅
│ │ ├── metrics.rs # 메트릭 수집
│ │ └── error.rs # 오류 처리
│ └── dto/ # Data Transfer Objects
│ ├── request.rs # 요청 DTO
│ └── response.rs # 응답 DTO
│
└── metrics/ # 메트릭 및 모니터링
├── mod.rs # Metrics 모듈 익스포트
├── backend.rs # 백엔드별 메트릭
├── routing.rs # 라우팅 메트릭
├── model.rs # 모델 서비스 메트릭
└── streaming.rs # 스트리밍 메트릭
tests/
├── integration/ # 통합 테스트
│ ├── health_test.rs # 헬스 엔드포인트 테스트
│ ├── chat_test.rs # 채팅 완료 테스트
│ ├── models_test.rs # 모델 목록 테스트
│ └── routing_test.rs # 라우팅 로직 테스트
├── unit/ # 단위 테스트
│ ├── core/ # Core 계층 테스트
│ ├── services/ # Service 계층 테스트
│ └── infrastructure/ # Infrastructure 테스트
└── common/ # 테스트 유틸리티
├── fixtures.rs # 테스트 픽스처
├── mocks.rs # 모킹 구현
└── helpers.rs # 테스트 헬퍼 함수
examples/
├── standalone_server.rs # 설정 파일로 최소 서버 실행
├── axum_integration.rs # 기존 Axum 앱에 라우터 임베딩
├── programmatic_config.rs # YAML 없이 코드로 설정
└── hot_reload.rs # 핫 리로드 및 설정 변경 구독
예제 실행¶
examples/ 디렉토리에는 라이브러리 API를 시연하는 실행 가능한 Rust 프로그램이 포함되어 있습니다. 다음 명령으로 예제를 실행할 수 있습니다:
예시:
# 독립 실행 서버 시작
cargo run --example standalone_server -- --config config.yaml
# 커스텀 Axum 앱에 라우터 임베딩
cargo run --example axum_integration -- --config config.yaml
# 프로그래밍 방식으로 설정 (YAML 파일 불필요)
OPENAI_API_KEY=sk-... cargo run --example programmatic_config
# 핫 리로드 시연
cargo run --example hot_reload -- --config config.yaml
자세한 내용은 라이브러리 사용법에서 임베딩 가능한 크레이트 API에 대한 전체 가이드를 참조하세요.
아키텍처 개요¶
의존성 흐름¶
HTTP Layer → Services Layer → Infrastructure Layer → Core Layer
↓ ↓ ↓ ↑
└────────────┴────────────────┴────────────────────┘
Core 타입 사용
주요 디자인 패턴¶
- 의존성 주입: 서비스가 컨테이너를 통해 주입됨
- 리포지토리 패턴: 백엔드 구현이 데이터 접근을 추상화
- 전략 패턴: 로드 밸런싱 전략이 플러그 가능
- 옵저버 패턴: 헬스 모니터링이 이벤트 기반 업데이트 사용
- 서킷 브레이커 상태 머신: 독립 상태 추적과 Admin 제어
- 백오프와 재시도: 일시적 실패 처리
빌드 및 실행¶
개발 빌드¶
# 빠른 개발 빌드
cargo build
# 디버그 출력과 함께 실행
RUST_LOG=debug ./target/debug/continuum-router
# 자동 리로드와 함께 실행
cargo watch -x run
# 특정 설정과 함께 실행
cargo run -- --config dev-config.yaml
릴리스 빌드¶
# 최적화된 릴리스 빌드 (기본적으로 모든 기능 활성화)
cargo build --release
# 릴리스 빌드 실행
./target/release/continuum-router
# 특정 기능만으로 빌드 (최소 라이브러리 빌드)
cargo build --lib --no-default-features --features "metrics,hot-reload"
Cargo 기능 플래그¶
크레이트는 선택적 구성 요소를 활성화하는 기능 플래그를 제공합니다. 바이너리 빌드 시에는 기본적으로 full 기능 세트가 활성화됩니다.
| 기능 | 설명 | 기본값 |
|---|---|---|
full | 아래 모든 기능 활성화 | yes (default 경유) |
cli | clap을 통한 CLI 바이너리 지원 | yes |
admin | 관리자 API 엔드포인트 | yes |
metrics | Prometheus 메트릭 엔드포인트 | yes |
files | Files API (/v1/files) | yes |
health-check | 백그라운드 헬스 모니터링 | yes |
hot-reload | 라이브 리로드를 위한 설정 파일 감시 | yes |
webui | 임베디드 WebUI 에셋 | yes |
gcp-auth | Gemini 서비스 계정용 Google Cloud 인증 | yes |
continuum-router를 라이브러리 크레이트로 사용할 때, 필요한 기능만 선택하여 컴파일 시간과 바이너리 크기를 줄일 수 있습니다:
[dependencies]
continuum-router = { git = "...", default-features = false, features = ["metrics", "hot-reload"] }
빌드 예시:
# 최소 코어 라이브러리 (선택적 의존성 없음)
cargo build --lib --no-default-features
# 메트릭 지원 라이브러리
cargo build --lib --no-default-features --features "metrics"
# 관리자 및 핫 리로드 라이브러리
cargo build --lib --no-default-features --features "admin,hot-reload"
# 전체 바이너리 (기본값)
cargo build --release
크로스 컴파일¶
# cross 설치
cargo install cross
# Linux x86_64용 빌드
cross build --release --target x86_64-unknown-linux-gnu
# macOS ARM64용 빌드
cross build --release --target aarch64-apple-darwin
# Windows용 빌드
cross build --release --target x86_64-pc-windows-gnu
테스트¶
테스트 실행¶
# 모든 테스트 실행
cargo test
# 출력과 함께 실행
cargo test -- --nocapture
# 특정 테스트 실행
cargo test test_health_check
# 단일 스레드로 테스트 실행 (디버깅용)
cargo test -- --test-threads=1
# 통합 테스트만 실행
cargo test --test integration
# 단위 테스트만 실행
cargo test --lib
# 문서 테스트 실행
cargo test --doc
테스트 작성¶
단위 테스트 예제¶
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_backend_selection() {
let backends = vec![
Backend::new("backend1", "http://localhost:8000"),
Backend::new("backend2", "http://localhost:8001"),
];
let selector = RoundRobinSelector::new(backends);
let selected = selector.select().unwrap();
assert_eq!(selected.name(), "backend1");
}
#[tokio::test]
async fn test_async_health_check() {
let backend = Backend::new("test", "http://localhost:8000");
let result = backend.health_check().await;
assert!(result.is_ok());
}
}
통합 테스트 예제¶
통합 테스트는 최상위 tests/*.rs 파일에 두며, 파일 하나가 Cargo 테스트 타깃 하나가 된다. tests/ 하위 디렉터리에 있는 .rs 파일은 최상위 타깃이 mod <dir>;로 선언해야만 컴파일되므로, 그 선언 없이 넣은 테스트는 아무 경고 없이 실행되지 않는다. 그런 파일이 생기면 tests/cargo_test_discovery_audit_test.rs가 빌드를 실패시킨다.
// tests/chat_test.rs
use continuum_router::test_utils::TestServer;
#[tokio::test]
async fn test_chat_completion() {
let server = TestServer::new().await;
let response = server
.post("/v1/chat/completions")
.json(&json!({
"model": "gpt-5.6-luna",
"messages": [{"role": "user", "content": "Hello"}]
}))
.send()
.await;
assert_eq!(response.status(), 200);
}
테스트 커버리지¶
# 커버리지 리포트 생성
cargo tarpaulin --out Html
# 특정 임계값과 함께 커버리지 생성
cargo tarpaulin --fail-under 80
# Codecov 리포트 생성
cargo tarpaulin --out Xml
스마트 라우팅 분류 정확도¶
tests/smart_routing_accuracy_test.rs는 규칙 기반 분류기의 classify_only 출력(src/services/smart_routing/router.rs)이 tests/data/smart_routing/dataset.json에 있는 레이블 데이터셋과 얼마나 일치하는지 측정하고, 분류기 모드별 혼동 행렬을 보고한다. 전체 리포트 실행:
같은 명령이 CI 게이트이기도 하다: accuracy_meets_the_regression_gate는 두 모드 중 하나라도 도메인 또는 복잡도 정확도가 테스트 파일의 DOMAIN_ACCURACY_GATE, COMPLEXITY_ACCURACY_GATE 옆에 기록된 임계값 아래로 떨어지면 빌드를 실패시킨다. 실패하는 실행에서는 리포트가 자동으로 출력되며, 통과하는 실행에서 리포트를 보려면 --nocapture만 있으면 된다.
두 가지 규칙 분류기 배포 모드를 측정한다(LLM/하이브리드 모드는 실제 또는 목(mock) 백엔드 왕복이 필요해 빠르고 결정적인 검사가 아니게 되므로 범위 밖이다): rule_default(primary_language 미설정)와 rule_primary_ko(primary_language: ko, 한국어 배포용 분류기). 이는 이슈 #1567을 위해 tests/classifier_language_parity_test.rs가 검증하는 것과 동일한 두 설정이며, 의도 신호가 없는 한국어 요청을 어떻게 읽는지에서만 차이가 난다: rule_default에서는 multilingual, rule_primary_ko에서는 general.
리포트 읽는 법¶
각 모드마다 전체 및 언어별 정확도, 도메인 혼동 행렬, 전체 복잡도 혼동 행렬, 언어별 복잡도 혼동 행렬, 그리고 복잡도 밴드가 틀린 케이스마다 한 줄씩 출력한다. 언어별 분해와 미스 목록은 #1605에서 추가했다. 합쳐진 행렬만으로는 혼동 셀이 코퍼스의 어느 쪽에서 왔는지 알 수 없고, 두 언어는 같은 방식으로 틀리지 않기 때문이다.
미스 한 줄은 id lang 기대값 -> 실제값 (방향) [신호] 형태다. 대괄호 안은 determine_complexity에 입력된 모든 신호이며, 이 함수가 직접 읽는 도메인 신호 세 개(code_blocks, math_notation, tool_definitions)도 포함해 이름=강도로 표시한다. 틀린 밴드를 추측하지 말고 이 목록으로 원인 신호까지 추적하라. 신호 벡터가 같은 두 케이스는 어떤 가중치나 경계값 변경으로도 구분할 수 없으며, COMPLEXITY_ACCURACY_GATE에 기록한 한계는 이렇게 확인한 것이다.
determine_complexity의 가중치나 밴드 경계를 바꿀 때는 통과하기 시작한 개별 픽스처가 아니라 움직인 혼동 셀로 근거를 대라. 59개 케이스에서는 셀 하나에 한두 개만 들어 있을 수 있고, 그것에 맞춘 변경은 과적합과 구분되지 않는다.
레이블이 붙은 케이스 추가하기¶
dataset.json의 각 항목은 다음과 같은 형태다:
{
"id": "code-fence-en",
"language": "en",
"text": "Please implement a function to reverse a string:\n```python\ndef reverse_string(s):\n pass\n```",
"expected": {
"rule_default": { "domain": "code", "complexity": "moderate" },
"rule_primary_ko": { "domain": "code", "complexity": "moderate" }
},
"note": "선택 사항: 이 레이블을 선택한 이유, 또는 이 케이스가 드러내려는 한계"
}
id는 고유하고 안정적이어야 한다. 이후 리포트가 어떤 케이스의 결과가 바뀌었는지 참조할 때 쓰인다.language는"en"또는"ko"이며, 리포트는 이 필드로 정확도를 분해해서 보여준다.text는 사용자 메시지다. 코드 도메인 신호를 테스트하려면 펜스 코드 블록(```)을, 수학 표기 신호를 테스트하려면 LaTeX 구분자($...$,\frac,\sum)를, 특정 의도 신호를 테스트하려면src/services/smart_routing/classifier_language.rs의 표에 있는 한국어 또는 영어 키워드를 사용한다.expected에는 러너가 실행하는 각 모드(현재는rule_default와rule_primary_ko)에 대한 항목이 하나씩 있어야 한다. 둘 중 하나라도 빠진 케이스는 조용히 건너뛰는 대신 명확한 패닉과 함께 테스트를 실패시킨다.src/services/smart_routing/types.rs의DomainTag/ComplexityLevel문서 주석을 읽는 사람 검토자가 해당 요청을 뭐라고 부를지를 기준으로 레이블을 붙이고, 분류기가 현재 출력하는 값을 그대로 베끼지 않는다. 분류기 자신의 출력을 레이블로 복사하면 정확도가 자동으로 100%가 되어 게이트가 무의미해진다. 독립적으로 레이블을 붙여야 향후 회귀가 실제 정확도 하락으로 드러난다. 분류기의 실제 출력이 여러분의 레이블과 다르다면, 이는note에 문서화할 가치가 있는 진짜 한계(데이터셋의creative-poem-ko,code-unmarked-ko예시 참고)이거나 여러분의 레이블을 다시 살펴봐야 한다는 신호이지, 조용히 출력값에 맞추라는 뜻이 아니다.- 데이터셋을 수정한 뒤에는 리포트 명령을 다시 실행하고,
tests/smart_routing_accuracy_test.rs의 게이트 상수 문서 주석(측정된 백분율, 두 실패 여유분, 각 게이트가 잡아내는 것과 잡아내지 못하는 것)을 새로 측정된 값에 맞춰 갱신한다. 실제로 측정한 값보다 게이트를 높게 설정하지 않는다.
코드 품질¶
포매팅¶
린팅¶
# 경고를 오류로 처리하여 clippy 실행
cargo clippy -- -D warnings
# pedantic 린트와 함께 clippy 실행
cargo clippy -- -W clippy::pedantic
# 자동 수정과 함께 clippy 실행
cargo clippy --fix
보안 감사¶
# 알려진 취약점 확인
cargo audit
# 취약한 의존성 수정
cargo audit fix
# 보안 리포트 생성
cargo audit --json > audit-report.json
문서화¶
# 문서 빌드
cargo doc
# 문서 빌드 및 열기
cargo doc --open
# 비공개 항목 포함하여 문서 빌드
cargo doc --document-private-items
# 문서 예제 확인
cargo test --doc
디버깅¶
디버그 로깅¶
# 디버그 로깅 활성화
RUST_LOG=debug cargo run
# 특정 모듈에 대해 trace 로깅 활성화
RUST_LOG=continuum_router::services=trace cargo run
# 구조화된 로깅 활성화
RUST_LOG=info RUST_LOG_FORMAT=json cargo run
디버거 사용¶
VS Code¶
.vscode/launch.json생성:
{
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Debug Router",
"cargo": {
"args": ["build", "--bin=continuum-router"],
"filter": {
"name": "continuum-router",
"kind": "bin"
}
},
"args": ["--config", "dev-config.yaml"],
"cwd": "${workspaceFolder}"
}
]
}
- 브레이크포인트 설정 후 F5 눌러 디버그
명령줄 (lldb)¶
# 디버그 심볼과 함께 빌드
cargo build
# lldb로 실행
lldb target/debug/continuum-router
# 브레이크포인트 설정
(lldb) b src/main.rs:50
# 프로그램 실행
(lldb) r --config config.yaml
메모리 디버깅¶
# valgrind 사용 (Linux)
valgrind --leak-check=full ./target/debug/continuum-router
# Address Sanitizer 사용
RUSTFLAGS="-Z sanitizer=address" cargo build -Z build-std --target x86_64-unknown-linux-gnu
./target/x86_64-unknown-linux-gnu/debug/continuum-router
성능 프로파일링¶
CPU 프로파일링¶
# 플레임 그래프 생성
cargo flamegraph -- --config config.yaml
# 특정 시나리오 프로파일
cargo flamegraph --bin continuum-router -- --benchmark
# perf 사용 (Linux)
perf record -g ./target/release/continuum-router
perf report
벤치마킹¶
# 벤치마크 실행
cargo bench
# 특정 벤치마크 실행
cargo bench routing
# 벤치마크 결과 비교
cargo bench -- --save-baseline main
git checkout feature-branch
cargo bench -- --baseline main
벤치마크 작성¶
// benches/routing_bench.rs
use criterion::{black_box, criterion_group, criterion_main, Criterion};
fn benchmark_routing(c: &mut Criterion) {
c.bench_function("round_robin_selection", |b| {
let selector = RoundRobinSelector::new(backends);
b.iter(|| {
selector.select(black_box(&request))
});
});
}
criterion_group!(benches, benchmark_routing);
criterion_main!(benches);
메모리 프로파일링¶
# heaptrack 사용 (Linux)
heaptrack ./target/release/continuum-router
heaptrack_gui heaptrack.continuum-router.*.gz
# Instruments 사용 (macOS)
cargo instruments -t Allocations
기여하기¶
개발 워크플로우¶
-
Fork 및 Clone
-
Feature 브랜치 생성
-
변경 사항 작성
- Rust 규칙을 따르는 코드 작성
- 새 기능에 대한 테스트 추가
-
문서 업데이트
-
변경 사항 테스트
-
변경 사항 커밋
-
Push 및 PR 생성
코드 표준¶
- Rust 명명 규칙 준수 (함수는 snake_case, 타입은 CamelCase)
- 모든 공개 API와 주요 분기에 테스트 작성 (커버리지 >90% 목표)
- 공개 API에 doc 주석으로 문서화
- 일관된 포매팅을 위해
cargo fmt사용 - 모든
cargo clippy경고 해결 - 함수를 작고 집중되게 유지
- 상속보다 합성 선호
- 적절한 오류 처리 사용 (Result/Option)
커밋 메시지 형식¶
Conventional Commits 사양 준수:
타입:
feat: 새 기능fix: 버그 수정docs: 문서만style: 코드 스타일 변경refactor: 코드 리팩토링perf: 성능 개선test: 테스트 추가chore: 유지보수 작업
Pull Request 가이드라인¶
- 제목: 명확하고 설명적
- 설명: 무엇을, 왜, 어떻게 설명
- 테스트: 새 기능에 대한 테스트 포함
- 문서: 관련 문서 업데이트
- Breaking Changes: 명확히 표시
- Issues: 관련 이슈 참조
리뷰 프로세스¶
- 자동화된 검사 통과 필수
- 최소 한 명의 메인테이너 승인
- 해결되지 않은 대화 없음
- main 브랜치와 최신 상태
문제 해결¶
일반적인 문제¶
컴파일 오류¶
테스트 실패¶
# 상세하게 테스트 실행
cargo test -- --nocapture --test-threads=1
# 경쟁 조건 확인
cargo test -- --test-threads=1
# 테스트 환경 확인
cargo test -- --ignored
성능 문제¶
# 릴리스 빌드 프로파일
cargo build --release
perf record ./target/release/continuum-router
perf report
# 블로킹 연산 확인
RUST_LOG=trace cargo run 2>&1 | grep "blocking"