몇 가지 방법으로 신호를 Cap'n Proto 위에 구현할 수 있습니다. 객체
의
체인은 캡의 프로토 RPC 호출을 완료하는 데 시간이 오래 복용에 아무 문제가 없습니다. 동일한 연결에있는 다른 통화는 정상적으로 계속 진행될 수 있으며 한 번에 많은 미해결 통화가있을 수 있습니다. 따라서 신호를 수신하기위한 한 가지 전략은 신호가 반환되기 전에 신호를 기다리는 호출을하는 것입니다.
많은 RPC 시스템은 걸려 오는 전화를 지원하지만 또 다른 문제가 있습니다. 신호 흐름이 있고 클라이언트가 신호를 스트림에서 관찰하는 것이 중요 할 경우 새로운 신호가 생성되면 상황이 복잡해집니다. 클라이언트가 RPC를 호출하여 읽는 것보다 빠릅니다. 각 클라이언트마다 버퍼를 유지해야합니다. 하지만 클라이언트가 죽고 요청을 중단하면 어떻게됩니까? 이제 당신은 그것을 지우는 어떤 종류의 타임 아웃이 필요합니다.
다른 대부분의 RPC 시스템과는 달리, Cap'n Proto는 새로운 개체를 즉석에서 생성하는 것을 지원합니다. 따라서 신호 흐름을 객체 체인으로 나타낼 수 있습니다. 예를 들어 :
struct MyPayload { ... }
interface MyInterface {
subscribe @0() -> (firstSignal :Signal(MyPayload));
# Subscribe to signals from this interface.
}
interface Signal(Type) {
# One signal in a stream of signals. Has a payload, and lets you
# wait for the next signal.
get @0() -> (value :Type);
# Gets the payload value of this signal. (Returns immediately.)
waitForNext @1() -> (nextSignal :Signal(Type));
# Waits for the next signal in the sequence, returning a new
# `Signal` object representing it.
}
이 크게 자동으로 클라이언트 측을 파괴하여 모든 클라이언트는 그들이 (그것으로 수행하는 것을 나타낼 즉시 각 개체의 소멸자를 호출 캡의 프로토 이후 서버 측에서 상태 관리를 단순화 참조, 일명 "떨어 뜨림"). 클라이언트가 연결을 끊으면 모든 참조가 암시 적으로 삭제됩니다.
콜백
캡의 프로토는 수 있기 때문에 양 방향으로 RPC 호출 (클라이언트 -> 서버 및 서버 -> 클라이언트), 당신은 콜백을 사용하는 메커니즘을 구독 /는 "신호"를 구현하거나 게시 할 수
struct MyPayload { ... }
interface MyInterface {
subscribe @0 (cb :Callback(MyPayload)) -> (handle :Handle);
}
interface Callback(Type) {
call @0 (value :Type);
}
interface Handle {}
클라이언트는 subscribe()
을 호출하고 콜백 객체 cb
을 전달합니다. 그런 다음 서버는 신호가있을 때마다 클라이언트를 다시 호출 할 수 있습니다. 은 메서드가없는 개체 인 Handle
을 반환합니다. 이것의 목적은 클라이언트가 구독을 취소 할 때를 탐지하는 것입니다. 클라이언트가 handle
을 삭제하면 서버에 통지되고 (서버 측 오브젝트의 소멸자가 실행 됨) 서버는 콜백 등록을 취소 할 수 있습니다.이것은 또한 클라이언트가 연결을 끊는 경우도 처리합니다. 연결 해제시 모든 객체 참조가 암시 적으로 삭제됩니다.
이 솔루션은 단순함으로 인해 체인 사물 솔루션보다 훨씬 좋아 보일 것입니다. 그러나 이제는 객체 참조가 양방향으로 가리켜져 사이클이 발생할 수있는 문제가 있습니다. 클라이언트 코드 내에서 콜백 구현이 등록 된 핸들을 "소유"하지 않도록주의해야합니다. 그렇지 않으면 연결이 닫힐 때를 제외하고는 정리되지 않습니다. 또한 서버가 콜백을 등록 해제 할 때까지 기다리는 동안 핸들을 놓은 후 잠시 동안 콜백을 호출 할 수 있는지 확인해야합니다. 이러한 문제는 체인 연결점 솔루션에 나타나지 않아 해당 솔루션을보다 명확하게 구현할 수 있습니다.
다른 RPC 시스템
은 내가 저자이기 때문에 위가 대부분의 RPC 시스템보다 더 많은 옵션을 제공하기 때문에 캡의 프로토 논의했다.
gRPC를 사용하는 경우 "스트리밍"기능을 사용하여 신호와 같은 것을 지원할 수 있습니다. 스트리밍 RPC는 시간이 지남에 따라 여러 응답을 반환 할 수 있습니다.
저는 Thrift에 대해 확신하지 않습니다. 마지막으로 시도한 결과, 요청은 FIFO 여야했기 때문에 장기 실행 RPC는 아니오였습니다. 그러나 그것은 오래 전이었고 그 이후로 변경되었을 수도 있습니다.
신호를 처음 수신 한 후 콜백 등록을 취소하지 않으려면 어떻게해야합니까? 어떻게 든 핸들을 어딘가에 보관해야한다는 것을 의미합니까? –
@VictorPolevoy 클라이언트는'Handle'을 메모리에 유지해야합니다. 아마도 전체 작업이 특정 라이브 네트워크 연결에 연결되어 있으므로 디스크에 저장하지 않을 것입니다. 연결이 끊어지면 콜백이 더 이상 작동하지 않습니다. 클라이언트는 다시 연결하여 새 콜백을 등록해야합니다. –
이전에 소켓에서받은 데이터 버퍼를 capnp에 제공하여 외부에서 소켓을 사용할 수 있습니까? –