13.4.3.2 node_id-port_name 포맷 기반 파이프 조립 및 데이터 타입(Data Type) 패닉(Segfault) 방어 지휘
분산 시스템의 거대한 파이프라인 그래프(DAG)를 설계할 때, YAML 디스크립터에서 수십 개의 노드들을 배관(Link)으로 이어 붙이는 작업은 마치 수만 가닥의 배선을 가진 전화 교환기를 눈을 감고 조립하는 것과 같다. Zenoh-Flow는 이 무자비한 연결도를 직관적으로 장악하기 위해 node_id와 port_name의 결합 문자열 포맷이라는 단순하면서도 엄격한 식별 규약을 강제한다.
하지만 연결 스펙이 명확해진다고 해서 런타임의 안전이 보장되는 것은 아니다. 카메라 노드에서 뱉어낸 C++ 이미지 바이트 덩어리를, 텍스트(String)를 기대하던 Python 언어의 자연어 처리 노드 구멍에 꽂아 넣게 되면, 역직렬화(Deserialization) 엔진은 형질의 괴리를 견디지 못하고 메모리 세그먼트 폴트(Segfault)를 뿜어내며 시스템을 자살로 몰고 간다. 본 절에서는 파이프라인 조립 문법의 뼈대와 더불어, 이기종 데이터 타입의 충돌 파국을 런타임 기동 전에 방어하는 타입 무결성(Type Integrity) 지휘 런북을 설파한다.
1. node_id-port_name 이중 식별자 결합 타게팅
매니페스트 상에서 링크(links)를 정의할 때, 수십 개의 오퍼레이터가 뚫어 놓은 수백 개의 포트 구멍을 헷갈리지 않고 정확히 타격하려면 노드의 거주지(node_id)와 해당 노드의 밸브 입구(port_name)를 이중으로 조준해야 한다.
Zenoh-Flow 선언 문법은 이 타게팅을 명확히 압축된 계층형(Hierarchical) 블록으로 분리 선언한다.
# [파이프 조립의 정밀 타게팅 런북]
links:
- from: # 1. 출발지 조준
node: "yolo_tracker_op" # (A) 먼저 노드를 찾고
output: "bounding_box_out" # (B) 그 노드의 어느 출력 밸브인지 지목
to: # 2. 도착지 조준
node: "trajectory_planner"
input: "obstacle_coords_in"
이 엄밀한 명세는 마치 IP 주소와 포트 번호(192.168.1.5:80)의 관계와 같다.
trajectory_planner 노드가 5개의 입력 포트를 가지고 있다 하더라도, 런타임 링커(Linker)는 다른 구멍을 절대 건드리지 않고 정확히 obstacle_coords_in 이라는 배관에만 YOLO의 텐서 좌표 바이트를 초당 60회씩 들이붓는다.
2. 데이터 타입 일치(Data Type Matching)의 비극과 런타임 블라인드
파이프 배관이 완벽하게 꽂혔다고 파이프라인이 정상적으로 돌아가는 것은 아니다.
YOLO 노드는 C++로 짠 커스텀 구조체 struct Bbox { float x,y,w,h; }; 를 바이트로 직렬화하여 배관에 던졌다. 그런데 도착지인 trajectory_planner 가 Python으로 짜여 있고, 입력 포트에서 protobuf 형식이나 단순 자연어 String 타입이 들어올 거라고 기대하고 있다면 어떻게 될까?
Zenoh의 와이어 프로토콜(Wire Protocol) 자체는 극도로 가볍기(Opaque) 때문에, 배관을 타고 지나가는 페이로드에 이 데이터가 “어떤 타입이다“라는 무거운 스키마(Schema) 장식표를 달아주지 않는다.
결과적으로 파이썬 노드는 C++의 순수 Float 바이트 덩어리를 억지로 UTF-8 문자열로 디코딩하려 시도하다가 파싱 에러(Parsing Error)를 토해내거나, 잘못된 메모리 번지를 침범하여 세그먼테이션 폴트(Segmentation Fault) 를 유발해 운영체제 커널로부터 강제 죽음(SIGKILL)을 선고받게 된다.
3. 선언적 타입 매칭(Type Hinting)과 컴파일/런타임 사전 방어
이 비참한 런타임 충돌 패닉을 배포 전에 색출해 내기 위해, 파이프라인 아키텍트는 오퍼레이터 바이너리의 인터페이스 선언부나 팩토리 래퍼에 엄격한 데이터 타입 힌팅(Type Hinting) 을 박아 넣어야만 한다.
오퍼레이터 노드 소스 코드를 작성할 때, “내 입력 포트 obstacle_coords_in 은 무조건 16바이트의 Float32Array 타입만 허용한다” 라고 구멍의 속성(Trait)을 명세(Manifestation)해 두는 것이다.
- 파이프라인 컴파일 페이즈 방어: Zenoh-Flow 데몬이
YAML파일을 읽고 노드들을 연결(Link)할 때, 양쪽 노드의 포트 명찰만 비교하는 것이 아니라 내부적으로 강제된 타입 시그니처(Type Signature) 를 사전 대조한다. 만약 출발지는Int64인데 도착지가Float32로 선언되어 있다면, 데몬은 연결 자체를 거부하고 데몬 기동 단계(Startup Phase)에서 파이프라인 생성을 중단명령(Abort)해 버린다. 로봇이 현장에 투입되어 피를 흘리기 전에 공장에서 불합격시키는 것이다. - 범용 직렬화 스키마(Serde/Protobuf/CDDL) 계약: 양측이 동일한 이기종 메모리 형질을 다룰 수 있도록 런타임 와이어 포맷을 CDR(DDS 기본), Protobuf, 혹은 MessagePack 등 단일 사투리(Dialect) 룰로 강제 통일하는 표준화 작업이 수반되어야 한다.
“관(Pipe)이 맞는다고 구멍형질(Type)이 맞는 것은 아니다.”
파이프 조립의 진정한 무결성은 노드 ID를 묶는 물리적 연결을 넘어, 메모리를 깨우는 직렬화 바이트가 양 끝단에서 완벽한 데칼코마니(거울상)의 형질 변환을 이루도록 강제하는 폭압적 타입 지배(Type Governance) 체계에서 비로소 완성된다.