How to use ServerContext::isCanceled() and AsyncNotifyWhenDone

1,398 views
Skip to first unread message

Okke Hendriks

unread,
Oct 13, 2016, 1:43:16 PM10/13/16
to grpc.io
I am unsure about how to use the ServerContext::isCanceled() functionality.

The ServerContext documentation (source code) says:  
// IsCancelled is always safe to call when using sync API
// When using async API, it is only safe to call IsCancelled after
// the AsyncNotifyWhenDone tag has been delivered
bool IsCancelled() const;

and:
// Async only. Has to be called before the rpc starts.
// Returns the tag in completion queue when the rpc finishes.
// IsCancelled() can then be called to check whether the rpc was cancelled.
void AsyncNotifyWhenDone(void* tag) {
 has_notify_when_done_tag_ = true;
 async_notify_when_done_tag_ = tag;
}

I have a function checking the ServerCompletionQueue as follows:
      template <class REP, class PERIOD>
   bool getFor(std::chrono::duration<REP, PERIOD> timeout)
   {
          void* tag;
     bool ok;

     typedef ::grpc::ServerCompletionQueue::NextStatus NextStatus;
     NextStatus nextStatus = notification_cq->AsyncNext(&tag, &ok, std::chrono::system_clock::now() + timeout);

     if(nextStatus == NextStatus::SHUTDOWN)
       return false;
     else if(nextStatus == NextStatus::TIMEOUT)
       return false;
     else if(nextStatus == NextStatus::GOT_EVENT)
     {
              if(ok)
         static_cast<ICallMetadata*>(tag)->process(ICallMetadata::EProcessType::NORMAL);
       else
       {
         PROCOM_DEBUG("NOT OK, RPC canceled or timed out or client crashed?");
         static_cast<ICallMetadata*>(tag)->process(ICallMetadata::EProcessType::CANCEL);
       }
       return true;
     }
     return false;
   }
ICallMetadata is a class which basically does what CallData does in the gRPC Async C++ examples.

What I want to do is the following:
If a client does multiple asynchronous calls, and cancels some of them at a later time, before they are processed (thus before AsyncNext got the new call). 
I want to never process the canceled calls. 

What I see is that I still get the event in the CompletionQueue (side note: And sometimes I get a not OK event, what does this mean exactly besides what the source comment says: "Upon success, true if read a regular event, false otherwise.". What is a regular event and what is a non-regular event? Is there some documentation about this?)

I can call AsyncNotifyWhenDone when creating a CallData object, but which tag should I use? (void*) CallData*? 
When receiving such a tag in the CompletionQueue, how do I know if I can safely call  IsCancelled()
So basically how am I supposed to match a AsyncNotifyWhenDone tag to a CallData tag? Is there some example where AsyncNotifyWhenDone is used?

If you need more information, please let me know.

Okke Hendriks

unread,
Oct 14, 2016, 7:55:04 AM10/14/16
to grpc.io
What seems to be the behavior of the Ok flag, after getting a event after a call to Next or AsyncNext:


Ok == TRUE implies one of the following (if using AsyncNotifyWhenDone):
  1. New RPC
  2. Finished RPC
  3. Canceled RPC 
Ok == FALSE implies:
  1. Called ::grpc::ServerAsyncResponseWriter<T>::finish(...) after RPC was canceled or timed out

Is there something missing /incorrect?
Reply all
Reply to author
Forward
0 new messages