#Cascade Screening 쿡북
버전: 0.43.0 | 업데이트: 2026-03-28 | 적용 대상: ranvier-runtime 0.36+ | 카테고리: 쿡북
#개요
Cascade screening은 대상이 여러 독립적인 필터를 순차적으로 통과하는 패턴입니다. 각 필터는 거부(단락)하거나 통과시킬 수 있습니다. 이 패턴은 다음과 같은 경우에 이상적입니다:
- 각 검사가 독립적으로 유효한 경우
- 조기 거부가 후속 연산을 절약하는 경우
- 검사 순서가 중요한 경우 (가장 저렴하거나 빠른 것부터)
- 각 필터를 독립적으로 테스트하고 교체할 수 있는 경우
#1. 패턴 구조
Input → Screen A → Screen B → Screen C → Screen D → Approved
↓ ↓ ↓ ↓
Reject A Reject B Reject C Reject D주요 특징:
- Fail-fast: 첫 번째 거부가 전체 파이프라인을 단락시킴
- 독립성: 각 필터는 다른 필터에 대해 알지 못함
- 순서: 효율성을 위해 가장 저렴하거나 빠른 검사를 먼저 배치
- 감사 가능성: 각 필터가 결정을 로깅함
#2. 적용 도메인: AML/KYC 컴플라이언스
신규 고객을 위한 4단계 컴플라이언스 스크리닝.
let screening = Axon::typed::<CustomerApplication, String>("kyc-screening")
.then(sanctions_check) // Screen 1: O(1) list lookup
.then(pep_check) // Screen 2: O(1) flag check
.then(risk_scoring) // Screen 3: O(n) algorithm
.then(document_verification); // Screen 4: expensive external API
// Screen order matters: sanctions check is instant, document
// verification calls an external API. Ordering cheapest-first
// avoids unnecessary API calls for sanctioned applicants.#각 필터를 Transition으로 구현
#[transition]
async fn sanctions_check(
applicant: CustomerApplication,
) -> Outcome<CustomerApplication, String> {
let sanctioned_countries = ["NK", "SY", "IR"];
if sanctioned_countries.contains(&applicant.country.as_str()) {
return Outcome::Fault(format!(
"Screen 1 REJECTED: {} from sanctioned country {}",
applicant.name, applicant.country
));
}
Outcome::Next(applicant)
}#3. 적용 도메인: 콘텐츠 검열
3단계 콘텐츠 검열 파이프라인.
let moderation = Axon::typed::<ContentSubmission, String>("content-moderation")
.then(spam_filter) // Fast regex/heuristic check
.then(toxicity_classifier) // ML model inference
.then(policy_enforcer); // Business rule evaluation#패턴 인사이트
스팸 필터(마이크로초)는 독성 분류기(밀리초)보다 먼저 실행됩니다. 콘텐츠가 명백한 스팸이면 비용이 많이 드는 ML 모델은 호출되지 않습니다.
#4. 적용 도메인: 세관 신고 스크리닝
수입 신고를 위한 다층 세관 스크리닝.
let customs = Axon::typed::<ImportDeclaration, String>("customs-screening")
.then(tariff_classification) // Classify goods by HS code
.then(restricted_goods_check) // Check against restricted list
.then(valuation_check) // Verify declared value
.then(origin_verification); // Country of origin rules#5. 감사 추적을 위한 Outcome::Emit 결합
각 필터는 파이프라인을 계속 진행하면서 감사 이벤트를 발행할 수 있습니다:
#[transition]
async fn pep_check(
mut applicant: CustomerApplication,
bus: &mut Bus,
) -> Outcome<CustomerApplication, String> {
let is_pep = check_pep_database(&applicant.name).await;
// Log the screen result to Bus for audit trail
bus.insert(ScreenResult {
screen: "pep",
passed: !is_pep,
timestamp: chrono::Utc::now(),
});
if is_pep {
Outcome::Fault("PEP check: flagged as politically exposed".into())
} else {
Outcome::Next(applicant)
}
}#6. Rule Chain과의 차이점
| 측면 | Cascade Screening | Rule Chain |
|---|---|---|
| 초점 | 필터링/거부 | 평가/점수 산정 |
| 거부 | 도메인 특화 로직 | 일반적인 임계값 |
| 출력 | 통과/거부 결정 | 적격성 결과 |
| 순서 | 성능 중심 | 로직 중심 |
둘 다 동일한 Axon 메커니즘(Outcome::Next / Outcome::Fault)을 사용하지만
의도가 다릅니다. Screening은 fail-fast 필터링을 강조하고,
rule chain은 포괄적인 평가를 강조합니다.
#빠른 참조
Start Template: ranvier new my-app --template screening
Example: cargo run -p cascade-screening
Pattern Tag: screening#참고 자료
cascade-screening예제 — 순수 Axon screening 데모compliance-demo예제 — Guards를 사용한 HTTP screeningcookbook_saga_compensation.md— 필터가 보상 가능한 액션을 트리거하는 경우