콘텐츠로 이동

개발 가이드

이 가이드는 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.tomlstyle_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

  1. rust-analyzer 확장 설치
  2. 디버깅을 위해 CodeLLDB 확장 설치
  3. 제공된 .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

  1. Rust 플러그인 설치
  2. 프로젝트 루트 열기
  3. Preferences → Build → Cargo에서 Cargo 설정 구성

Vim/Neovim

  1. Mason 또는 수동으로 rust-analyzer 설치
  2. LSP 클라이언트 구성 (nvim-lspconfig, coc.nvim 등)
  3. 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 <이름> [-- <인수>]

예시:

# 독립 실행 서버 시작
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 타입 사용

주요 디자인 패턴

  1. 의존성 주입: 서비스가 컨테이너를 통해 주입됨
  2. 리포지토리 패턴: 백엔드 구현이 데이터 접근을 추상화
  3. 전략 패턴: 로드 밸런싱 전략이 플러그 가능
  4. 옵저버 패턴: 헬스 모니터링이 이벤트 기반 업데이트 사용
  5. 서킷 브레이커 상태 머신: 독립 상태 추적과 Admin 제어
  6. 백오프와 재시도: 일시적 실패 처리

빌드 및 실행

개발 빌드

# 빠른 개발 빌드
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에 있는 레이블 데이터셋과 얼마나 일치하는지 측정하고, 분류기 모드별 혼동 행렬을 보고한다. 전체 리포트 실행:

cargo test --test smart_routing_accuracy_test -- --nocapture

같은 명령이 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_defaultrule_primary_ko)에 대한 항목이 하나씩 있어야 한다. 둘 중 하나라도 빠진 케이스는 조용히 건너뛰는 대신 명확한 패닉과 함께 테스트를 실패시킨다.
  • src/services/smart_routing/types.rsDomainTag/ComplexityLevel 문서 주석을 읽는 사람 검토자가 해당 요청을 뭐라고 부를지를 기준으로 레이블을 붙이고, 분류기가 현재 출력하는 값을 그대로 베끼지 않는다. 분류기 자신의 출력을 레이블로 복사하면 정확도가 자동으로 100%가 되어 게이트가 무의미해진다. 독립적으로 레이블을 붙여야 향후 회귀가 실제 정확도 하락으로 드러난다. 분류기의 실제 출력이 여러분의 레이블과 다르다면, 이는 note에 문서화할 가치가 있는 진짜 한계(데이터셋의 creative-poem-ko, code-unmarked-ko 예시 참고)이거나 여러분의 레이블을 다시 살펴봐야 한다는 신호이지, 조용히 출력값에 맞추라는 뜻이 아니다.
  • 데이터셋을 수정한 뒤에는 리포트 명령을 다시 실행하고, tests/smart_routing_accuracy_test.rs의 게이트 상수 문서 주석(측정된 백분율, 두 실패 여유분, 각 게이트가 잡아내는 것과 잡아내지 못하는 것)을 새로 측정된 값에 맞춰 갱신한다. 실제로 측정한 값보다 게이트를 높게 설정하지 않는다.

코드 품질

포매팅

# 모든 코드 포맷
cargo fmt

# 변경 없이 포매팅 확인
cargo fmt -- --check

# 특정 파일 포맷
cargo fmt -- src/main.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

  1. .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}"
    }
  ]
}
  1. 브레이크포인트 설정 후 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

기여하기

개발 워크플로우

  1. Fork 및 Clone

    git clone https://github.com/YOUR_USERNAME/continuum-router.git
    cd continuum-router
    

  2. Feature 브랜치 생성

    git checkout -b feature/amazing-feature
    

  3. 변경 사항 작성

  4. Rust 규칙을 따르는 코드 작성
  5. 새 기능에 대한 테스트 추가
  6. 문서 업데이트

  7. 변경 사항 테스트

    cargo test
    cargo fmt
    cargo clippy -- -D warnings
    

  8. 변경 사항 커밋

    git add .
    git commit -m "feat: Add amazing feature"
    

  9. Push 및 PR 생성

    git push origin feature/amazing-feature
    

코드 표준

  • Rust 명명 규칙 준수 (함수는 snake_case, 타입은 CamelCase)
  • 모든 공개 API와 주요 분기에 테스트 작성 (커버리지 >90% 목표)
  • 공개 API에 doc 주석으로 문서화
  • 일관된 포매팅을 위해 cargo fmt 사용
  • 모든 cargo clippy 경고 해결
  • 함수를 작고 집중되게 유지
  • 상속보다 합성 선호
  • 적절한 오류 처리 사용 (Result/Option)

커밋 메시지 형식

Conventional Commits 사양 준수:

<type>(<scope>): <subject>

<body>

<footer>

타입:

  • feat: 새 기능
  • fix: 버그 수정
  • docs: 문서만
  • style: 코드 스타일 변경
  • refactor: 코드 리팩토링
  • perf: 성능 개선
  • test: 테스트 추가
  • chore: 유지보수 작업

Pull Request 가이드라인

  1. 제목: 명확하고 설명적
  2. 설명: 무엇을, 왜, 어떻게 설명
  3. 테스트: 새 기능에 대한 테스트 포함
  4. 문서: 관련 문서 업데이트
  5. Breaking Changes: 명확히 표시
  6. Issues: 관련 이슈 참조

리뷰 프로세스

  1. 자동화된 검사 통과 필수
  2. 최소 한 명의 메인테이너 승인
  3. 해결되지 않은 대화 없음
  4. main 브랜치와 최신 상태

문제 해결

일반적인 문제

컴파일 오류

# 빌드 캐시 정리
cargo clean

# 의존성 업데이트
cargo update

# 충돌하는 기능 확인
cargo tree --duplicates

테스트 실패

# 상세하게 테스트 실행
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"

리소스