분산 워커 관측 Part C — useNodeStatus 3초 폴링 훅 + statusVisual 색/라벨 매핑 + 2D 워커 카드 그리드 + raw three.js 파이프라인 시각화(정상=시안 파티클 흐름 / busy=가속 / paused=앰버 정지 / degraded=주황 / down=빨강 끊김, Redis 끊김=버스 빨강). GET /api/agent-office/nodes(Part B) 소비. r3f 대신 기설치 three 직접 사용. WebGL 미지원 시 카드 폴백 + 3D/그리드 토글. vitest 10 passed, build OK. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019LV86jBozkNhSFXJA412fq
70 lines
2.1 KiB
JavaScript
70 lines
2.1 KiB
JavaScript
// src/pages/infra/statusVisual.js
|
|
// 상태 → 색/라벨 매핑. 2D 패널과 Three.js 파이프라인이 공유하는 단일 진실원천.
|
|
// 색은 index.css 테마 팔레트와 일치(neon-cyan healthy, amber paused, orange degraded, red down).
|
|
|
|
export const LINK_COLORS = {
|
|
healthy: '#00d4ff', // neon-cyan — 통신이 흐름
|
|
paused: '#fbbf24', // amber — 작업중(트레이딩) 일시정지
|
|
degraded: '#fb923c', // orange — dead-letter 누적
|
|
down: '#f43f5e', // red — 워커 다운/링크 끊김
|
|
};
|
|
|
|
const NEUTRAL = '#4a5572';
|
|
|
|
export function linkColor(status) {
|
|
return LINK_COLORS[status] || NEUTRAL;
|
|
}
|
|
|
|
// 워커 객체 → 사람이 읽는 상태 라벨
|
|
export function workerStateLabel(w) {
|
|
if (!w || !w.alive) return '오프라인';
|
|
switch (w.state) {
|
|
case 'paused':
|
|
return '일시정지';
|
|
case 'busy':
|
|
return '처리 중';
|
|
case 'idle':
|
|
return '대기';
|
|
case 'market_open':
|
|
return '장중';
|
|
case 'market_closed':
|
|
return '휴장';
|
|
default:
|
|
return '온라인';
|
|
}
|
|
}
|
|
|
|
// 워커 객체 → 링크 status 도출(2D/3D 공통). collect_status의 link 산정과 동일 규칙.
|
|
export function workerStatus(w) {
|
|
if (!w || !w.alive) return 'down';
|
|
if (w.state === 'paused') return 'paused';
|
|
if ((w.dead_letter || 0) > 0) return 'degraded';
|
|
return 'healthy';
|
|
}
|
|
|
|
export function workerColor(w) {
|
|
return linkColor(workerStatus(w));
|
|
}
|
|
|
|
// 워커 내부명 → 표시 타이틀
|
|
export const WORKER_TITLES = {
|
|
'music-render': 'Music Render',
|
|
'video-render': 'Video Render',
|
|
'image-render': 'Image Render',
|
|
'insta-render': 'Insta Render',
|
|
'task-watcher': 'Task Watcher',
|
|
ai_trade: 'AI Trade',
|
|
};
|
|
|
|
export function workerTitle(name) {
|
|
return WORKER_TITLES[name] || name;
|
|
}
|
|
|
|
// kind → 한 줄 역할
|
|
export function kindLabel(kind) {
|
|
if (kind === 'render') return '렌더 워커';
|
|
if (kind === 'watcher') return '작업 감시';
|
|
if (kind === 'trader') return '트레이딩';
|
|
return kind || '';
|
|
}
|