Cap'n Proto 1.0
(capnproto.org)- RPC cancellation opt-in 방식이
context.allowCancellation()호출에서 schema의allowCancellationannotation으로 변경됨 context.allowCancellation()을 쓰지 않은 사용자는 1.0 업그레이드 때 변경이 필요 없고, cancellation은 기본적으로 계속 비허용 상태임- 1.0은 장기 지원(LTS) 성격의 릴리스로, 1.0 branch에 bugfix를 장기적으로 backport할 계획임
- Cap’n Proto RPC 성능 개선으로 RPC 구현과 KJ I/O framework의 메모리 할당 감소, 일부 RPC protocol message 생략, 작은 message buffering 개선을 통한 syscall 감소가 적용됨
- KJ가 MacOS와 BSD 계열에서 비동기 I/O 처리에
kqueue()를 사용하며, 기존의 더 느린poll()기반 방식에서 변경됨 - KJ HTTP client와 server 구현이
CONNECTmethod를 지원함 capnp::RevocableServer가 추가되어 wrapper가 lifetime을 제어하지 않는 객체를 RPC wrapper로 export할 때 use-after-free bug 회피를 돕는 구조 제공- 2.0 개발은 새
v2branch에서 진행하고,masterbranch는 기존 프로젝트가 변경으로 중단되지 않도록 1.0 LTS branch가 되는 계획임 - 2.0 계획은 serialization format이나 RPC protocol의 하위 호환성 없는 변경이 아니라 C++ API와 KJ 중심 변경이며, 다른 언어로 작성된 애플리케이션은 영향을 받지 않음
- 2.0 계획에는 C++20 또는 C++23 compiler 요구, C++20 coroutine 사용, exception disabled와 no-RTTI mode 지원 중단,
kj::Maybe와kj::AsyncOutputStreamAPI 변경 등이 포함됨
댓글과 토론
Hacker News 의견들
-
Cap'n Proto와 Sandstorm 커뮤니티에 매우 안타까운 소식을 전함. Go 구현의 핵심 기여자였던 Ian Denhardt(HN의 zenhack)가 몇 주 전 갑작스럽게 세상을 떠났고, 지난 3년간 함께 많이 협업하며 친구가 되었기에 큰 상실감을 느낌
사실상 프로젝트 리드로서 이제 Ian의 큰 빈자리를 메워야 하므로, 프로젝트에 기여할 수 있다면 도움이 절실함. C++, Rust 등 다른 구현의 기여자나 메인테이너라면 꼭 연락하고 싶음. Ian의 작업을 이어가려면 매우 똑똑한 사람들과 함께해야 함
RIP Ian, 함께 일하며 정말 많이 배웠음. 연락처: https://github.com/lthibault, https://matrix.to/#/#go-capnp:matrix.org, Telegram @lthibault, gmail louist87- 갑자기 떠난 사람들을 몇 번 겪어봤는데, 정말 영혼이 무너지는 일임. 그런 일이 생길 때마다 삶이 얼마나 연약한지, 모든 것이 얼마나 빨리 바뀔 수 있는지 떠올리게 됨
미래를 외면하지는 않지만, 삶의 작은 것들을 더 즐기려 노력하게 되었음. Ian은 많은 사람에게 닿은 놀라운 유산을 남겼음. RIP Ian - 몰랐던 소식이라 충격적임. Ian의 블로그를 정말 좋아했는데 너무 안타까움
- @zenhack은 Haskell 바인딩도 관리했던 것으로 보임
- 직접 알지는 못했지만, Sandstorm을 되살리려던 최근 포크인 Tempest 작업을 크게 존경했음. 이 소식을 알려줘서 고마움
- 정말 슬픈 소식임. Ian은 많은 이에게 영감을 줬고, 커뮤니티 전체에 큰 상실이 될 것임
- 갑자기 떠난 사람들을 몇 번 겪어봤는데, 정말 영혼이 무너지는 일임. 그런 일이 생길 때마다 삶이 얼마나 연약한지, 모든 것이 얼마나 빨리 바뀔 수 있는지 떠올리게 됨
-
Cap'n Proto 외에 프로미스 파이프라이닝을 가진 프로토콜이 이렇게 적다는 점이 놀라움. 떠오르는 다른 예는 9p뿐인데, 9p는 범용 프로토콜은 아님
https://capnproto.org/news/2013-12-13-promise-pipelining-cap...- 멋진 기능이긴 하지만, 명시적으로 질의를 묶는 방식에 비해 백엔드를 최적화하기 어려울 것 같음. 예를 들어 파이프라인된 여러 개의 별도 RPC 호출보다, 단일 SQL 질의로 끝나는 맞춤형 RPC 호출이 더 나을 수 있음
그래도 더 널리 쓰일 법한 기능이긴 함 - 파이프라이닝은 좋지 않은 아이디어임. 객체 인스턴스를 실체화하기 때문에 견고한 구현이 훨씬 어려워짐. 더 이상 무상태 호출이 아니라 특정 객체 인스턴스에 대해 함수를 실행하는 구조가 됨
예를 들어 클라이언트 Joe가 Service A를 호출하고 그 약속된 결과를 Service B에 넘기면, Service B는 그 프로미스 결과를 얻기 위해 Service A로 원격 호출을 해야 함
이때 보안 경계가 즉시 복잡해짐. 위임 모델을 어떻게 할 것인가도 문제지만, 더 심각한 건 역압력이 사라진다는 점임. 클라이언트 Joe가 Service A에 수천 개 호출을 만들고 아직 실체화되지 않은 결과를 Service B에 넘기면, Service A가 DDoS처럼 몰려 Service B가 시간 초과될 수 있음 - 9p에 프로미스 파이프라이닝이 있는 줄 몰랐음. 더 정확히는 클라이언트가 파일 디스크립터를 선택할 수 있어서, 파일을 열자마자 그 파일을 읽는 요청을 보낼 수 있고, 열기가 실패하면 읽기도 EBADF로 실패하는 구조라 멋짐
다만 프로미스 파이프라이닝은 클라이언트 지원도 필요함. 사용자가 여러 walk를 발행하면 첫 walk 응답을 기다리지 않고 모두 보내는 9p 클라이언트가 있는지 궁금함
또한 9p는 파일 디스크립터에 대해서만 프로미스 파이프라이닝을 제공함. 이것만으로도 많은 걸 할 수 있지만, 디렉터리의 모든 파일을 읽고 싶다면 read를 발행한 뒤 그 read 결과로 walk할 수 있어야 하는데 9p는 이를 지원하지 않는 듯함. 내 원격 시스템 호출 프로토콜 라이브러리인 rsyscall에서는 실제로 이걸 지원함 - Cap'n Proto의 정신적 조상으로는 Mark Miller의 E 언어와 함께 개발된 CapTP/VatTP, 일명 Pluribus가 있음. 이름 장난으로 “unum”이라는 장치도 있음. 더 깊은 계보는 그의 논문을 보면 되고, 여기에는 Barbara Liskov의 프로미스 파이프라이닝과 CLU 확장 Argus의 관련 아이디어들도 나옴
Mark Miller는 나중에 JavaScript의 프로미스 제안도 쓴 것으로 기억함. 다만 RPC 확장은 실현되지 않았고, 대신 파이프라이닝과는 잘 맞지 않아 보이는 async/await를 얻게 됨
E의 방식으로 분산 권한 시스템을 만들려는 더 최근 시도인 Spritely Goblins와 OCapN도 파이프라이닝을 추구하므로, cap-talk에 있으면 실제 사용 사례는 적더라도 비슷한 프로토콜 몇 개를 더 들을 수 있을 것임
다만 멋진 기능이긴 해도, 프로미스 파이프라이닝은 실제 명시적 프로미스로 프로그래밍해야 하는 듯하고, 그게 얼마나 까다로워질 수 있는지는 이미 잘 알려져 있음
반대편, 즉 이벤트 루프와 협력적 동시 실행 “능동 객체” 쪽에서 흥미롭고 덜 알려진 아이디어로는 DCOM/COM+의 causality IDs가 있음. 재진입성을 제어하는 수단이며 Microsoft 문서의 CoGetCurrentLogicalThreadId와 Effective COM의 CALLTYPE_TOPLEVEL_CALLPENDING 논의를 보면 됨. 나중에는 Win8/UWP의 ASTA에서 새 기능처럼 팔려고 했던 것 같음
[1] http://erights.org/elib/distrib/captp/index.html
[2] http://erights.org/talks/thesis/index.html
[3] https://spritely.institute/goblins/
[4] https://github.com/ocapn/ocapn
[5] https://groups.google.com/g/captalk/
[6] https://learn.microsoft.com/openspecs/windows_protocols/ms-d...
[7] https://learn.microsoft.com/windows/win32/api/combaseapi/nf-...
[8] https://archive.org/details/effectivecom50wa00boxd/page/150
[9] https://devblogs.microsoft.com/oldnewthing/20210224-00/?p=10... - Cap'n Proto의 프로미스 파이프라이닝이 정확히 어떻게 동작하는지는 모르지만, 디렉터리를 읽고 그 안의 모든 항목에 stat을 걸거나, 응답값 두 개 중 하나만 다음 호출에 넘기고 싶을 때가 걱정됨
후자는 어떻게든 가능할 것 같지만, 전자는 결과 목록의 값 개수 등에 의존함
- 멋진 기능이긴 하지만, 명시적으로 질의를 묶는 방식에 비해 백엔드를 최적화하기 어려울 것 같음. 예를 들어 파이프라인된 여러 개의 별도 RPC 호출보다, 단일 SQL 질의로 끝나는 맞춤형 RPC 호출이 더 나을 수 있음
-
출시 축하함. 10년 만이라 정말 신날 듯함. 앞으로 다른 언어 구현에도 더 작업이 있을지 궁금함
포맷 아이디어는 정말 마음에 들지만, 우리 스택의 주 언어들은 제품에 쓰고 싶을 만큼 지원되지 않음- 이 부분이 실제로 Cap'n Proto의 가장 큰 약점임. 내가 제대로 관리하는 것은 C++ 구현뿐이고, 다른 구현은 여러 기여자에게서 나오기 때문에 완성도와 품질 수준이 다양함
안타깝지만 여기서 새로운 것을 약속하기는 어려움. Cap'n Proto 작업은 내 주 프로젝트인 Cloudflare Workers 런타임의 필요에 의해 움직이고, 이는 주로 C++임. Go와 Rust 서비스와도 상호작용하며, 해당 구현들은 거기서는 역할을 해내는 것으로 보임
다시 말해 Cap'n Proto는 오픈소스 프로젝트이고 사람들에게 유용하길 바라지만, 내가 팔려는 제품은 아니므로 모두가 채택하게 만드는 데 특별히 집중하지는 않음. 언제나 그렇듯 기여는 환영함
큰 변화가 있을 수 있는 한 가지 경우는 Cloudflare가 Cap'n Proto를 Workers 플랫폼의 공개 기능으로 만들기로 결정하는 때임. 그러면 여러 언어에서 정말 다듬어야 할 직접적인 필요가 생김. 가끔 논의는 하지만 현재 계획은 없음 - C++ 구현을 감싼 래퍼가 아니라 RPC 계층을 직접 작성하려던 사람들이 있었지만, 직접적 이득에 비해 다시 써야 할 코드가 정말 많음
시도해보고 싶다면 해봐도 됨. 사람들은 꽤 협조적일 가능성이 큼. 다만 단순히 일이 아주 많다는 점은 알아야 함
- 이 부분이 실제로 Cap'n Proto의 가장 큰 약점임. 내가 제대로 관리하는 것은 C++ 구현뿐이고, 다른 구현은 여러 기여자에게서 나오기 때문에 완성도와 품질 수준이 다양함
-
배경을 덧붙이면, Kenton은 Google의 사내 proto 시스템을 수년간 운영하다가 떠난 뒤 자신의 오픈소스 버전을 만들었음
- 아마 그가 protobuf를 오픈소스로 공개한 사람일 것임
-
Cloudflare 직원 중 Cap'n Proto를 protobuf 같은 다른 것보다 선택하는 데 관여한 사람이 있다면, 어떤 고려가 있었는지 궁금함. 그 이유가 나에게도 중요한 것인지, 아니면 엄청난 규모를 다루지 않으면 신경 쓰지 않아도 되는 것인지 알고 싶음
- Cloudflare가 2014년에 Cap'n Proto를 사용한 내용을 다룬 블로그 글이 있음. 내가 합류하기 3년 전임: https://blog.cloudflare.com/introducing-lua-capnproto-better...
지금도 Cloudflare의 데이터 파이프라인, 즉 엣지에서 로그와 분석을 만드는 시스템은 대체로 Cap'n Proto 직렬화에 기반함. 나는 그 프로젝트에는 개인적으로 많이 관여하지 않았음
Cloudflare Workers의 경우에는 내가 프로젝트를 시작했으니 내 것을 쓴 것임. 아마 원하는 설명은 아닐 것임
그래도 Cap'n Proto의 RPC 프로토콜이 대안들보다 훨씬 표현력이 높아서, Workers Runtime의 샌드박싱 구현과 Durable Objects 같은 분산 시스템 기능 구현에 큰 도움이 되었다고 봄. https://blog.cloudflare.com/introducing-workers-durable-obje... - Cloudflare에서 일하지는 않지만 그들의 작업을 따라보고, 가끔 성능에 민감한 프로젝트를 다룸. 추측하자면 Cap'n Proto, flatbuffers, SBE 등은 Avro나 protobuf 같은 다른 데이터 포맷과는 별도의 범주로 봤을 것임
Parquet 같은 열 지향이 아니라 레코드에 가까운 형태의 데이터를 택하고, 선행 파싱 시간이 사실상 0인 형식을 원한다면 선택지는 꽤 짧아짐. 읽을 때 필드 값을 바꾸면 마샬링은 있을 수 있음
https://capnproto.org/news/2014-06-17-capnproto-flatbuffers-...에서 이 절충점을 다룸
Cap'n Proto는 원래 https://sandstorm.io/를 위해 만들어졌고, Kenton이 Cloudflare에 고용된 뒤 했을 그 작업은 결국 Cloudflare Workers로 이어졌을 것임
또 다른 고려 사항: https://github.com/google/flatbuffers/issues/2#issuecomment-... - 내가 합류한 지 1년 조금 지난 시점의 상황을 요약하면, Cloudflare는 엣지에서 중앙 지점으로 로그를 보내 고객 분석과 엔터프라이즈 고객용 로그 제공을 하는 방식을 만들고 있었음
그 전체를 구축한 핵심 엔지니어 Albert Strasheim이 유력한 직렬화 옵션들을 벤치마크했고, Cap'n Proto가 protobuf보다 꽤 빠르다는 결과를 얻은 것으로 이해함
훌륭한 C++ 구현이 있었고, nginx에서 사용할 수 있었음. 기억하기로는 약간의 Lua도 관여했음. 소비 쪽에서 쓰던 Go 구현에는 거친 부분이 있었지만, 필요한 핵심 부분은 사람들이 고칠 수 있었음
Cloudflare는 늘 머신 비용 효율을 중요하게 여겼기 때문에, 당시 성능 요구를 고려하면 자연스러운 선택이었음. 데이터 팀에 있던 동안 Cap'n Proto는 작업하기 꽤 쉬웠고, 중앙 스키마 저장소에서 proto 정의를 공유하는 방식도 잘 작동했음 - Cloudflare Workers의 리드 개발자가 Cap'n Proto의 창시자라서 선택이 쉬웠을 가능성이 큼
- Cloudflare가 2014년에 Cap'n Proto를 사용한 내용을 다룬 블로그 글이 있음. 내가 합류하기 3년 전임: https://blog.cloudflare.com/introducing-lua-capnproto-better...
-
Cap'n Proto가 OCapN 표준화 작업에 참여하는 점이 기대됨. 이게 Cap'n Proto 2.0 작업의 일부가 될지 궁금함
https://github.com/ocapn/ocapn- 안타깝게도 그 참여를 이끌던 Ian “zenhack” Denhardt가 최근 갑작스럽게 세상을 떠났음
나는 OCapN을 좋아하지만, 지금 맡고 있는 일들이 많아 개인적으로 얼마나 시간을 투입할 수 있을지 모르겠음. 더 좋은 소식을 전할 수 있으면 좋겠지만, 우리 모두에게 비극적인 상실임
- 안타깝게도 그 참여를 이끌던 Ian “zenhack” Denhardt가 최근 갑작스럽게 세상을 떠났음
-
Cap'n Proto를 써본 적은 없지만, 프로토콜에서 필수 필드가 왜 문제가 되는지 설명한 kentonv의 매우 유익한 FAQ 답변 [1]에 감사함
사람들이 protobuf 3에 왜 required 필드가 없냐고 물을 때마다 자주 링크함
[1] https://capnproto.org/faq.html#how-do-i-make-a-field-require...- 정말 가치 있는 관점임. 나도 예전에는 왜 그런지 이해하기 어려웠음. 핵심은 protobuf와 Cap'n Proto를, 단일 버전의 단일 프로세스가 보는 세상을 나타내는 메모리 내 자료구조가 아니라, API 경계를 넘어 서로 다른 스키마 버전과 하위·상위 호환으로 동작해야 하는 직렬화 형식으로 이해하는 것이었음
따라서 “불법 상태를 표현 불가능하게 만들라”는 널리 반복되는 만트라는 여기에 적용되지 않음 - Typical은 타입 진화를 돕기 위해 비대칭 필드를 제공함:
https://github.com/stepchowfun/typical#asymmetric-fields-can...
필수 필드를 안전하게 추가하고 제거하도록, Typical은 선택 필드와 필수 필드 사이의 중간 상태인 asymmetric을 제공함. 구조체의 asymmetric 필드는 쓰는 쪽에는 필수로, 읽는 쪽에는 선택으로 간주됨. 선택 필드와 달리 asymmetric 필드는 필수로 안전하게 승격하거나 반대로 되돌릴 수 있음 - 이 논리를 확장하면 사실상 모든 정적 타입을 없애자는 결론도 가능하지 않나 싶음. 솔직히 완전히 틀린 말도 아니고, Alan Kay가 객체지향을 동적 타입과 후기 바인딩으로 정의한 이유이기도 함. 그런데 우리는 그와 반대로 가면서 같은 교훈을 계속 다시 배우고 있음
- FAQ [1]에는 “올바른 답은 애플리케이션이 필요에 따라 애플리케이션 수준 코드에서 검증하는 것”이라고 되어 있음
애플리케이션 코드에 의존하는 대신 필수 메시지 검증을 켜고 끌 수 있는 매개변수가 있었으면 좋았을 것임. 애플리케이션 내부나 메시지 버스에서는 끌 수 있지만, 일반적으로는 켜져 있으면 개발자에게 큰 도움이 됨
[1] https://capnproto.org/faq.html#how-do-i-make-a-field-require... - 같은 맥락의 함정이 하나 더 있음. 생성된 클라이언트에서 받는 것처럼 필요 없는 것까지 역직렬화되는 문제임
Go의 인터페이스에서 정말 좋아하는 점은 내가 쓰는 것만 원격으로 타입화하고 나머지는 건너뛸 수 있다는 점임. 서비스가 쓰지도 않는 계약 변경 때문에 장애가 나는 것은 즐겁지 않고, 찾기도 어려움
- 정말 가치 있는 관점임. 나도 예전에는 왜 그런지 이해하기 어려웠음. 핵심은 protobuf와 Cap'n Proto를, 단일 버전의 단일 프로세스가 보는 세상을 나타내는 메모리 내 자료구조가 아니라, API 경계를 넘어 서로 다른 스키마 버전과 하위·상위 호환으로 동작해야 하는 직렬화 형식으로 이해하는 것이었음
-
훌륭한 성과임. 솔직히 말하면 Cap'n Proto를 추천하지는 않겠음. C++ API가 매우 어색함
무복사 파싱의 이점도 기대보다 작음. 사용성이 어색해서 데이터를 Cap'n Proto 자료구조로 계속 들고 있고 싶을 가능성이 낮고, 99%는 결국 자기 자료구조로 복사하게 됨
세상은 이런 종류의 이진 구현에서 대체로 Protobuf에 정착했기 때문에 다른 시스템과의 마찰도 더 큼
나는 직렬화 용도로만 써봤음. RPC 쪽은 더 매력적일 수도 있음
Protobuf/gRPC 대신 Thrift가 성공했으면 정말 좋았을 것임. 이전이나 이후에 본 어떤 것보다 설계가 훨씬 좋고 유연했음. 주로 형편없는 문서 때문에 사라진 것 같고, 뒤에 큰 이름이 없었던 것도 이유였을 듯함- 무복사에 필요한 API가 특히 쓰기 쪽에서 좀 어색해진다는 점에는 동의함. 읽기 쪽은 크게 다르지 않음. 한편 무복사는 mmap()과 함께 쓰는 경우 같은 특정 시나리오에서만 패러다임 전환에 가깝고, 네트워크 통신에서는 RDMA 같은 강한 기법을 쓰지 않는 한 크게 바뀌지 않음
무복사가 별로 중요하지 않은 사용 사례를 위해 Cap'n Proto에 “평범한 C 구조체” 또는 그에 가까운 형태를 쓰고, protobuf처럼 한 번 복사하는 직렬화를 제공하는 선택적 대체 API를 늘 추가하고 싶었지만 아직 하지 못했음
다만 개인적으로는 직렬화보다 RPC 프로토콜에 훨씬 더 흥미를 느껴왔음. RPC 프로토콜은 사소하지 않은 거의 모든 사용 사례에서 실제 패러다임 전환이라고 생각함 - protobuf가 아니라 flatbuffers를 말하는 것 같음. 사실상 표준으로 자리 잡았고, 몇몇 다른 곳에서는 SBE를 씀
어쨌든 이진 직렬화의 주요 문제는 스키마와 메시지 버전 관리, 그리고 델타 인코딩임. 이 둘을 무시하면 평평한 이진 직렬화는 사소함
위 두 가지를 모두 잘 다루는 해법을 제공하는 라이브러리는 없음 - 스키마가 필요 없다면 MessagePack이 꽤 훌륭하다고 봄. 다만 V8의 JSON 직렬화가 비정상적으로 빠라서 MessagePack도 이기기 어렵고, 다른 언어에서는 더 빠른 경우가 많으며 바이트 수를 줄여주긴 함
- fbthrift는 아직도 잘 살아 있음
- 무복사에 필요한 API가 특히 쓰기 쪽에서 좀 어색해진다는 점에는 동의함. 읽기 쪽은 크게 다르지 않음. 한편 무복사는 mmap()과 함께 쓰는 경우 같은 특정 시나리오에서만 패러다임 전환에 가깝고, 네트워크 통신에서는 RDMA 같은 강한 기법을 쓰지 않는 한 크게 바뀌지 않음
-
capnp의 아이디어는 늘 마음에 들었지만, 결국 메시지 인코딩 프로토콜인 것이 내 서버 아키텍처를 어떻게 짜야 하는지까지 의견을 갖고 있다는 점이 거슬림
gRPC도 확실히 이런 문제가 있지만 protobuf와는 아주 명확히 분리되어 있고, protobuf에는 gRPC 관련 기능이 있긴 함
이런 얽힘 때문에 capnp와 비교할 때마다 flatbuffers나 protobuf 쪽으로 기울게 됨. 특히 fb와 pb 구현이 훨씬 단순해지고, 보안과 유지보수 측면에서 단순성을 매우 높게 보기 때문임
좋은 서드파티 언어 구현이 부족한 것도 이 판단이 타당하다는 직접적인 신호라고 봄. 버스 팩터와 장기 생존성도 매우 나쁨. 단순성이 지배함- cap'n'proto에 접근할 때마다 겪은 문제는 서버 아키텍처에 의견이 있다는 것뿐 아니라, C++에서는 STL의 매우 의견 강한 대안인 KJ까지 함께 가져온다는 점임. 몇 년 전 만져봤을 때 기존 코드베이스 곳곳에 손을 뻗어 들어가 작업하기 어려웠음
Rust 버전도 자체적인 규범적 생활양식을 요구함. 그중 많은 부분은 무복사 세계관에서는 말이 되지만, 그래도 여러 표현을 어렵게 만들고 문서도 읽기 힘들었음
그래서 이 이유 하나만으로도 보통 flatbuffers를 고르게 됨
그래도 언젠가 cap'n'proto가 필요하고 유용한 상황이 오길 바라며, 수년간 써보려고 포크해둔 여러 취미 프로젝트 중 하나라도 끝내고 싶음. 고품질 엔지니어링이 들어간 건 맞음 - 직렬화 계층이 RPC 선택에 어떻게 영향을 주는지 궁금함
- cap'n'proto에 접근할 때마다 겪은 문제는 서버 아키텍처에 의견이 있다는 것뿐 아니라, C++에서는 STL의 매우 의견 강한 대안인 KJ까지 함께 가져온다는 점임. 몇 년 전 만져봤을 때 기존 코드베이스 곳곳에 손을 뻗어 들어가 작업하기 어려웠음
-
새롭지는 않지만, 이름이 Star Trek Voyager에 대한 의도적 오마주인지, 아니면 내가 모르는 다른 참조가 있는지 궁금함
https://memory-alpha.fandom.com/wiki/Captain_Proton- 그 참조는 실제로 생각해본 적이 없음
Cap'n Proto라는 이름은 원래 Capabilities and Protobufs를 뜻했음. Protocol Buffers 기반의 권한 기반 RPC 프로토콜이었음. 하지만 초기에 완전히 다른 직렬화 형식을 시도해보고 싶어졌음. 그래도 “Proto”는 프로토콜이라는 뜻으로 여전히 맞아서 이름을 유지했음
“cerealization protocol”이라는 말장난은 사실 다른 사람이 알려준 것이지만, 곧바로 로고에 추가했음 - “cerealization protocol”이라고 홍보하길래, 항상 Cap'n Crunch 시리얼 참조라고 생각했음
- 그 참조는 실제로 생각해본 적이 없음