refactor(topics): 멀티 에이전트용 지식 재편 — _Common(공통 기본기) + Domain_* 구조
에이전트 8종(대화형/프로그래머 C·S/디자이너/설계자/기획자/QA/PD/PM)에게 [공통 기본 능력 + 롤별 Specialty] 2층으로 지식을 주입하기 위한 재분류. 문서 내용·포맷은 무수정, 폴더 이동만 (6,372개 문서 수 보존 확인). - Topic_Programming → Domain_Programming (내부 구조 보존) - Topic_Graphic → Domain_Design - Topic_Business → Domain_Product - Topic_General → Domain_General - _Common 신설: Math(구 Topic_Math_Specialty), Reasoning(구 General/From_Thinking & Reasoning), Reasoning_Creativity(구 General/From_창의성), Communication(Poetic_Blog_Writing + From_writing) - 타 도메인의 From_* 폴더는 유지 (출처 표기일 뿐, 이미 도메인에 맞게 분류된 문서) - 빈 폴더 정리 (memory/procedures) - 에이전트→폴더 매핑은 workspace의 .astra/agent-knowledge-map.json (9개 에이전트) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,242 @@
|
||||
---
|
||||
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 |
|
||||
Reference in New Issue
Block a user