Files
2nd/10_Wiki/Topics/Architecture/Mediator Topology.md
T
Antigravity Agent f8b21af4be Wiki cleanup: error-doc removal, dedup merge, link normalization
10_Wiki/Topics 대규모 정리:
- 오류 캡처/미완성 stub 문서 227개 제거
- 교차폴더 중복 43클러스터 병합 (63파일 → redirect)
- 링크명 정규화: 깨진 링크 수정·redirect 직결·개념 매핑 ~2,400건
- 카테고리 MOC 6개 신규 생성
- Graph 섹션 미해결 related-keyword 링크 10,058건 제거

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 23:52:15 +09:00

243 lines
8.8 KiB
Markdown

---
id: wiki-2026-0508-mediator-topology
title: Mediator Topology
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [Event Mediator Topology, Mediator-Based Event-Driven Architecture]
duplicate_of: none
source_trust_level: A
confidence_score: 0.9
verification_status: applied
tags: [event-driven, architecture-topology, orchestration]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: typescript
framework: temporal
---
# Mediator Topology
## 매 한 줄
> **"매 central orchestrator 가 매 multi-step event flow 를 직접 지휘"**. Mark Richards, *Software Architecture Patterns* — Event-Driven Architecture 의 두 topology 중 하나 (다른 하나는 Broker). Mediator 는 매 sequence + error handling + transactional rollback 이 필요한 매 complex workflow 에 적합. 2026 의 modern 구현: Temporal, AWS Step Functions, Camunda 8, Netflix Conductor.
## 매 핵심
### 매 Mediator vs Broker (Richards 의 dichotomy)
- **Broker**: 매 chain of events, decentralized, 매 service 가 매 다음 step 결정. Pub/sub. 매 simple, fast, hard-to-orchestrate complex workflow.
- **Mediator**: 매 central event mediator 가 매 process 를 orchestrate. 매 sequence 명시, 매 error handling 중앙화. 매 complex but observable.
### 매 Mediator components
1. **Event Queue**: incoming initial events.
2. **Event Mediator**: 매 process orchestrator (workflow engine).
3. **Event Channel**: mediator → processor 의 dispatch.
4. **Event Processor**: 매 single step 실행 (idempotent worker).
### 매 응용 (when to use mediator)
1. Order fulfillment (validate → pay → reserve → ship → notify).
2. Loan approval (multi-stage with human-in-loop).
3. Subscription onboarding.
4. ETL/data pipeline with retries and DLQ.
5. SAGA pattern compensation orchestration.
### 매 trade-off vs Broker
- **More observable**: 매 mediator 의 single source of truth for workflow state.
- **More coupled**: 매 mediator 의 process knowledge — 매 evolution 시 central change.
- **Lower throughput**: 매 mediator 의 single point.
- **Easier to reason**: 매 sequence 가 명시 — debugging.
## 💻 패턴
### 1. Temporal workflow (mediator, 2026 standard)
```typescript
// activities.ts (event processors)
export async function validateOrder(o: Order) { /* ... */ }
export async function chargePayment(o: Order) { /* ... */ }
export async function reserveInventory(o: Order) { /* ... */ }
export async function ship(o: Order) { /* ... */ }
export async function notify(userId: string) { /* ... */ }
// workflow.ts (mediator)
import { proxyActivities } from "@temporalio/workflow";
import type * as activities from "./activities";
const acts = proxyActivities<typeof activities>({
startToCloseTimeout: "1 minute",
retry: { maximumAttempts: 5 },
});
export async function orderWorkflow(order: Order) {
await acts.validateOrder(order);
try {
await acts.chargePayment(order);
await acts.reserveInventory(order);
await acts.ship(order);
} catch (err) {
// SAGA compensation
await acts.refundPayment(order).catch(() => {});
await acts.releaseInventory(order).catch(() => {});
throw err;
}
await acts.notify(order.userId);
}
```
### 2. AWS Step Functions (managed mediator)
```json
{
"StartAt": "Validate",
"States": {
"Validate": { "Type": "Task", "Resource": "...:validate", "Next": "Charge" },
"Charge": { "Type": "Task", "Resource": "...:charge",
"Catch": [{ "ErrorEquals": ["PaymentError"], "Next": "Refund" }],
"Next": "Reserve" },
"Reserve": { "Type": "Task", "Resource": "...:reserve", "Next": "Ship" },
"Ship": { "Type": "Task", "Resource": "...:ship", "Next": "Notify" },
"Notify": { "Type": "Task", "Resource": "...:notify", "End": true },
"Refund": { "Type": "Task", "Resource": "...:refund", "Next": "Fail" },
"Fail": { "Type": "Fail" }
}
}
```
### 3. Camunda 8 (BPMN mediator)
```xml
<!-- order.bpmn (visual model, executable) -->
<bpmn:process id="orderProcess">
<bpmn:startEvent id="OrderReceived" />
<bpmn:serviceTask id="Validate" zeebe:type="validate-order" />
<bpmn:serviceTask id="Charge" zeebe:type="charge-payment" />
<bpmn:exclusiveGateway id="ChargeOk?" />
<bpmn:serviceTask id="Reserve" zeebe:type="reserve-inventory" />
<!-- ... compensation events for SAGA -->
</bpmn:process>
```
### 4. Custom mediator (lightweight)
```typescript
type Step<S> = { name: string; run: (s: S) => Promise<S>; compensate?: (s: S) => Promise<void> };
class Mediator<S> {
constructor(private steps: Step<S>[]) {}
async execute(initial: S): Promise<S> {
const completed: Step<S>[] = [];
let state = initial;
try {
for (const step of this.steps) {
state = await step.run(state);
completed.push(step);
}
return state;
} catch (err) {
// SAGA compensate in reverse
for (const step of completed.reverse()) {
await step.compensate?.(state).catch(() => {});
}
throw err;
}
}
}
const orderMediator = new Mediator<Order>([
{ name: "validate", run: validateOrder },
{ name: "charge", run: chargePayment, compensate: refundPayment },
{ name: "reserve", run: reserveInventory, compensate: releaseInventory },
{ name: "ship", run: ship },
]);
```
### 5. Broker (contrast — for comparison)
```typescript
// No central mediator. Each service publishes its own next event.
// order-service: emits "order.validated"
// payment-service: subscribes "order.validated" → publishes "order.paid"
// inventory-service: subscribes "order.paid" → publishes "inventory.reserved"
// shipping-service: subscribes "inventory.reserved" → publishes "order.shipped"
//
// Pros: decoupled, scalable
// Cons: workflow knowledge scattered, hard to add/reorder steps
```
### 6. Compensation pattern (SAGA)
```typescript
// Within mediator, each step has forward + compensating action
const steps = [
{ do: chargePayment, undo: refundPayment },
{ do: reserveInventory, undo: releaseInventory },
{ do: scheduleShipment, undo: cancelShipment },
];
async function saga<S>(state: S) {
const done: typeof steps = [];
for (const s of steps) {
try { await s.do(state); done.push(s); }
catch {
for (const d of done.reverse()) await d.undo(state).catch(() => {});
throw new Error("saga compensated");
}
}
}
```
### 7. Idempotency (essential for mediator workers)
```typescript
async function chargePayment(order: Order) {
const idempotencyKey = `charge:${order.id}`;
const existing = await db.idempotency.findOne(idempotencyKey);
if (existing) return existing.result;
const result = await stripe.charges.create({
amount: order.amount,
customer: order.customerId,
idempotency_key: idempotencyKey,
});
await db.idempotency.put(idempotencyKey, result);
return result;
}
// Mediator may retry → worker MUST be idempotent.
```
## 매 결정 기준
| 상황 | Topology |
|---|---|
| <5 step linear flow, simple notify | Broker (pub/sub). |
| Multi-step with rollback / SAGA | Mediator. |
| Long-running (hours/days) workflow | Mediator (Temporal/Step Functions). |
| Human approval steps | Mediator (BPMN — Camunda). |
| High-throughput stream (>10k/s) | Broker (Kafka). |
| Audit + visibility critical | Mediator. |
| Loose coupling priority | Broker. |
**기본값**: complex business process 는 매 Mediator (Temporal). Simple notification/log 는 매 Broker (Kafka/SNS).
## 🔗 Graph
- 부모: [[Event-Driven Architecture]]
- 변형: [[Broker Topology]]
- 응용: [[Temporal]]
- Adjacent: [[Idempotency]]
## 🤖 LLM 활용
**언제**: workflow architecture choice, SAGA design, multi-step business process modeling, retry/compensation strategy.
**언제 X**: 매 simple fire-and-forget event, 매 high-throughput streaming (broker preferred).
## ❌ 안티패턴
- **God mediator**: 매 매 모든 process 가 매 single mediator 에 — 매 monolith of orchestration. 매 domain 별 분리.
- **Non-idempotent worker**: 매 mediator retry → 매 double-charge / double-ship. 매 idempotency key 필수.
- **Mediator knows business rules**: 매 if/else 분기 가 매 mediator 에 — workflow engine 의 limit. 매 decision 은 activity 로 push.
- **Sync mediator for slow steps**: 매 mediator 가 매 slow IO 의 inline wait — 매 timeout. 매 async + signal/callback.
- **No timeout/retry policy**: 매 hung workflow 의 매 stuck instance.
- **Compensation 누락**: 매 SAGA 의 매 partial commit 의 매 inconsistent state.
## 🧪 검증 / 중복
- Verified (Richards, *Software Architecture Patterns* O'Reilly 2015; Temporal docs; Hohpe & Woolf, *Enterprise Integration Patterns* — Process Manager).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Mediator vs Broker + Temporal/Step Functions/Camunda 2026 implementations |