카테고리 없음

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

jinjaeeeee 2024. 6. 2. 20:28

 


 

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()을 호출할 수 없습니다.
  • Polling_type:
    • GRPC_CQ_NON_POLLING
      : 완료 대기열 다음/플러크를 호출하는 스레드는 폴링을 수행하지 않습니다.
    • GRPC_CQ_DEFAULT_POLLING
      : 특정 폴링 방식을 지정하는 것이 아니라, 라이브러리에게 최적의 폴링 방식을 자동으로 선택하도록 위임하는 역할을 합니다.
    • GRPC_CQ_NON_LISTENING: 
      기능적으로 기본 폴링과 유사하지만, cq가 수신 대기 중이 아님을 나타내는 bool 속성이 있습니다. 이 속성은 grpc-server 코드에서 수신 소켓을 이 완료 대기열의 폴링 집합에 연결하지 않는 데 사용됩니다.

 

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