[gRPC] CompletionQueue: 비동기 이벤트 관리

CompletionQueue는 비동기 서버와 클라이언트에서 이벤트를 관리하는 중요한 구성 요소입니다.
비동기 프로그래밍을 다룰 때 빠질 수 없는 구성 요소가 바로 CompletionQueue입니다. 이 구성 요소는 비동기 작업의 시작과 완료를 깔끔하게 관리해주며, 서버와 클라이언트 양쪽에서 모두 활용됩니다.
서버나 클라이언트가 비동기 작업을 시작할 때 사용되며, 해당 작업이 완료되었을 때 알림을 받기 위해 사용됩니다.
기본적으로 CompletionQueue는 다음과 같은 작업을 수행합니다:
1. 태그 추가
: 비동기 작업이 시작되면, 작업을 식별할 수 있는 태그(tag)가 CompletionQueue에 추가됩니다.
2. 태그 제거/알림
: 비동기 작업이 완료되면, 해당 태그가 CompletionQueue에서 빠져나와 작업이 완료되었다는 것을 알립니다.
Next() 또는 AsyncNext() 메서드를 호출하여 완료된 이벤트를 가져올 수 있습니다.
메서드 호출 결과로 반환되는 태그를 통해 어떤 작업이 완료되었는지 식별할 수 있습니다.
예를 들어, 서버에서는 클라이언트의 다양한 요청을 비동기적으로 처리할 수 있습니다.
클라이언트의 요청 -> 이를 처리하는 비동기 작업이 시작 -> 해당 작업을 식별을 위한 태그가 CompletionQueue에 추가
작업이 완료되면, CompletionQueue는 해당 태그를 제거하여 작업 완료를 알립니다.
완료 대기열에는 두 가지 속성이 있습니다.
- Completion_type:
- GRPC_CQ_NEXT
: grpc_complement_queue_next()를 호출할 수 있습니다
(단, grpc_complement_queue_pluck()은 호출할 수 없음). - GRPC_CQ_PLUCK
: grpc_complete_queue_pluck()을 호출할 수 있습니다
(grpc_complete_queue_next()는 호출할 수 없음). - GRPC_CQ_CALLBACK
: 큐의 태그는 콜백에 대한 함수 포인터입니다.
또한 이 태그에는 next() 또는 pluck()을 호출할 수 없습니다.
- GRPC_CQ_NEXT
- Polling_type:
- GRPC_CQ_NON_POLLING
: 완료 대기열 다음/플러크를 호출하는 스레드는 폴링을 수행하지 않습니다. - GRPC_CQ_DEFAULT_POLLING
: 특정 폴링 방식을 지정하는 것이 아니라, 라이브러리에게 최적의 폴링 방식을 자동으로 선택하도록 위임하는 역할을 합니다. - GRPC_CQ_NON_LISTENING:
기능적으로 기본 폴링과 유사하지만, cq가 수신 대기 중이 아님을 나타내는 bool 속성이 있습니다. 이 속성은 grpc-server 코드에서 수신 소켓을 이 완료 대기열의 폴링 집합에 연결하지 않는 데 사용됩니다.
- GRPC_CQ_NON_POLLING
grpc_completion_queue_attributes cq_attrs = GRPC_CQ_DEFAULT_ATTRS;
cq_attrs.grpc_cq_polling_type = GRPC_CQ_DEFAULT_POLLING;
grpc_completion_queue* cq = grpc_completion_queue_create_for_next(&cq_attrs);

grpc_completion_queue_next(cq, deadline)/pluck(cq, deadline, tag)
1. 이벤트가 완료 대기열에 큐에 대기 중인 경우 큐를 해제하고 반환합니다
(pluck()의 경우 해당 태그가 관심 있는 태그인 경우에만 큐를 해제합니다).
2. 완료 큐 종료 반환
3. pluck()의 경우, (tag, worker) 쌍을 cq의 태그<->작업자 맵에 추가합니다.
폴링을 수행하려면 grpc_pollset_work(cq's-pollset, deadline)를 호출합니다.
4. grpc_pollset_work(cq's-pollset, deadline)를 호출하여 폴링을 수행합니다.
이 함수가 읽기/쓰기 가능/오류가 있는 일부 fd를 발견했다면 해당 클로징을 예약했을 것입니다
(반드시 이 완료 큐가 아니라 일부 완료 큐에 완료 이벤트를 큐에 대기시킬 수 있음).
grpc_cq_end_op(cq, tag)
1. 이벤트 큐에 태그를 큐에 넣습니다.
2. 완료 큐에 해당하는 폴셋을 찾습니다.
(i) cq가 GRPC_CQ_NEXT 유형인 경우, 모든 작업자를 킥합니다.
즉, grpc_pollset_kick(pollset, nullptr)을 호출합니다.
(ii) cq가 GRPC_CQ_PLUCK 타입이면, 완료 대기열에서 태그<->작업자
맵을 검색하여 작업자를 찾습니다. 그런 다음 구체적으로 해당 워커를 킥합니다.
즉, grpc_pollset_kick(pollset, worker)을 호출합니다.
gRPC Completion Queue
Author: Sree Kuchibhotla (@sreecha) - Sep 2018
https://chromium.googlesource.com/external/github.com/grpc/grpc/+/master/doc/core/grpc-cq.md
gRPC Completion Queue
gRPC Completion Queue Author: Sree Kuchibhotla (@sreecha) - Sep 2018 Code: completion_queue.cc This document gives an overview of completion queue architecture and focuses mainly on the interaction between completion queue and the Polling engine layer. Com
chromium.googlesource.com