20.6.3.1 파이프라인 매니페스트(YAML) 다이어그램의 컴포넌트 간 I-O 타입 불일치(Mismatch) 추적

20.6.3.1 파이프라인 매니페스트(YAML) 다이어그램의 컴포넌트 간 I-O 타입 불일치(Mismatch) 추적

분산 데이터플로우 파이프라인(Zenoh-Flow)을 조립할 때, 개발자는 코드 컴파일의 빡빡함 대신 우아하고 느긋한 YAML 매니페스트 한 장으로 노드와 노드 사이의 배관(Link)을 잇는다.

  • Node A (Camera Source) \rightarrow Node B (TensorFlow Operator)
    매우 이상적인 그림이다.

하지만 어느 순간 파이프라인 시스템을 기동했는데 데이터가 노드 B 근처에도 가지 못한 채 소멸해 버리는 끔찍한 사막화(Data Blackhole)를 겪게 된다. 데몬은 에러도 뿜어내지 않는다!
파이프라인 백엔드의 가장 악랄하고 교묘한 크래시는 컴파일단이 아닌 논리(Logical) 설계도면단에서 발생한다. 바로 Node A 가 뱉어낸 C++ 객체 형식(Output Type)과, Node B 가 받으려고 벌리고 있는 주둥이의 형식(Input Type)이 은밀하게 엇갈려 있는 I/O 타입 불일치(Mismatch) 크래시다.

본 절에서는 런타임에 에러 없이 조용히 데이터를 삼켜버리는 이 기만적 파이프라인 침묵 현상을 색출해 내고 정적 분석으로 사전 압살 시키는 I/O 정합성 타격 런북을 갈파한다.

1. 약결합(Loosely-Coupled) 그래프의 함정과 묵시적 파멸

C++ 이나 Rust 코드로 단일 모놀리식 바이너리를 짤 땐, 함수 A()int 를 반환하는데 B(string) 에 밀어 넣으면 컴파일러가 강력한 에러를 뱉으며 빌드 자체를 막아버린다 (Type Safety).

하지만 Zenoh-Flow 는 각 연산 노드를 이미 바이너리로 포장된 별개의 라이브러리(.so 파일) 로 분리시킨다. 그리고 YAML 을 통해 느슨하게 엮어낸다.

# [재앙이 숨겨져 있는 지옥의 파이프라인 YAML 배관]
links:
  # Camera 노드의 C++ 엔진은 "std::vector<uint8_t>" 바이트 배열을 Output으로 뱉는다.
  # 그러나 ObjectDetection 노드는 "cv::Mat" 비전 포인터 객체가 Input으로 들어오길 기다리고 있다!
  - from: { node: "Camera", output: "frame" }
    to: { node: "ObjectDetection", input: "image" }

YAML 은 너무나 문법적으로 완벽한(Syntax Correct) 텍스트이기 때문에 구동 시 파서(Parser)를 가볍게 통과한다.
하지만 런타임에 막상 첫 캡슐(zflow::Data)이 Camera 노드에서 날아올 때, 수신단인 ObjectDetection 플러그인의 메모리 캐스팅 try_cast<cv::Mat>() 루틴은 실패한다.
데몬 코어는 타입이 맞지 않으면 이를 C++ 크래시(Segfault)로 터트리는 대신 “아, 내가 처리할 수 없는 패킷이네” 하고 조용히 묵시적 드랍(Silent Drop) 을 강행하고 다음 큐를 기다린다! 로봇은 장애 로그 하나 남기지 않은 채 영원한 소경이 되어버린다.

2. 타입 바인딩의 무덤: 플러그인 메타데이터(Metadata) 명세 강제 명령

이 무능한 침묵을 파괴하기 위해, 아키텍트는 오퍼레이터(Operator) 노드를 짜는 말단 프로그래머들에게 “자신의 플러그인 포트가 어떤 데이터를 물고 뱉는지” C++ 코드 안의 전역 심볼(Symbol) 매크로로 이중 삼중 명세(Metadata Declaration)하도록 강압적 팩토리 규칙을 박아넣어야 한다.

// [오퍼레이터 노드 I/O 족쇄(Type Safety Tracker) 인젝션 런북]

// 내가 만든 "ObjectDetection" 노드의 구멍 규격을 데몬 파서에게 미리 멱살 잡혀 고시한다!
ZFLOW_OPERATOR_CONFIG(
    "ObjectDetection", 
    zflow::Inputs<zflow::Port<cv::Mat, "image">>,  // 내 입구(Input)엔 무조건 'cv::Mat'만 받는다.
    zflow::Outputs<zflow::Port<std::string, "bounding_box">>
)

3. 데몬 런타임 그래프 유효성 검사(Graph Validation)의 선행 점화

모든 노드가 저렇게 C++ 코어단에서 고유의 자료형 Type ID 를 헤더에 장착하게 되면, 데몬을 띄우는 사령관(zenoh-flow-daemon)은 파이프라인 모터 시동을 걸기 0.1초 전 에 거대한 정적 분석 위재(Dry-Run Validation) 심문을 수행한다.

데몬 코어는 YAML 문서를 읽으면서 Camera 의 Output 포트 타입 ID(vector<uint8_t>)와 ObjectDetection 의 Input 포트 타입 ID(cv::Mat) 메모리 식별자를 대조한다.
두 개의 바이트 타입 시그니처가 정확하게 일치하지 않는다! 데몬은 런타임 시작 버튼을 절단하고 굉음을 낸다!

[FATAL] Pipeline Link Mismatch Error: Cannot pipe Node 'Camera(vector<uint8_t>)' into Node 'ObjectDetection(cv::Mat)'. Execution Halted!

파이프라인이 구동된 뒤에 소리 없이 데이터가 블랙홀(Silent Drop)로 빨려가는 미친 짓을, 데이터가 흐르기도 전인 런타임 초기화 0단계에서 치명적 에러 패닉(Panic)을 터트려 개발자의 설계도 타락을 면전(Fail-Fast)에서 척살(Halt)하는 시스템 통치력. 분산 객체와 YAML 의 오만함이 불러오는 가장 어두운 망각을, 프레임워크 코어의 명세 강요(Type Introspection)로 사전 도륙하는 아키텍트의 승리 공식이다.