Hello
I wanted to make use of IsCancelled in async server to stop processing 
requests that were cancelled by user.
In order to use ServerContext::IsCancelled method I had to call 
ServerContext::AsyncNotifyWhenDone first.
And then some problems occurred.

*1.* I took a greeter_async_server.cc from grpc cpp examples and added 
ctx.AsyncNotifyWhenDone(this);
https://github.com/pszemus/grpc/blob/79b1464b277d6e438fd9032addc5d7224cc9f56b/examples/cpp/helloworld/greeter_async_server.cc#L97

After executing a request the server crashes (
https://github.com/grpc/grpc/issues/20155).
If I drop deleting the CallData object in FINISH state it turns out that 
there are 2 events from CompletionQueue at the end of request processing:
Server listening on 0.0.0.0:50051 
Proceeding call 0x4e25550 with status 0 
Proceeding call 0x4e25550 with status 1 
Proceeding call 0x4e25550 with status 2 
Proceeding call 0x4e25550 with status 2
So I think that's why the server crashes - with the first FINISH state the 
CallData is being freed and the second event cannot operate on deleted 
object.

*2.* If there're always 2 events from CompletionQueue at the end I can 
introduce new transitive state of CallData.
https://github.com/pszemus/grpc/blob/f5db1153b78626da4460a6cdaa2f11e48a78dcab/examples/cpp/helloworld/greeter_async_server.cc#L116

Then the request is processed through all 4 states (and CallData is freed 
only once at the last one of them):
Proceeding call 0x4e25550 with status 0
Proceeding call 0x4e25550 with status 1 
Proceeding call 0x4e25550 with status 2 
Proceeding call 0x4e25550 with status 3
Almost OK...

*3. *As said in 
https://github.com/pszemus/grpc/blob/f5db1153b78626da4460a6cdaa2f11e48a78dcab/examples/cpp/helloworld/greeter_async_server.cc#L149
 I 
want to span HandleRpcs across multiple threads.
Without AsyncNotifyWhenDone it works really great, but after enabling it, 
those 2 events sent at the end of request processing, can be received by 2 
seperate threads, leading to race condition while changing the state of 
CallData and not being freed at all (CallData maintains in FINISH state and 
never proceeds to CLEANUP state).
https://github.com/pszemus/grpc/blob/b7839549fead5090958eb3539f8754d69eb532e8/examples/cpp/helloworld/greeter_async_server.cc#L70
[*140135346489088*] Proceeding call 0x7f73b800a090 with status 0
[*140135346489088*] Proceeding call 0x7f73a8000b20 with status 1
[*140135346489088*] Proceeding call 0x7f73a8000b20 with status 2
[*140134984972032*] Proceeding call 0x7f73a8000b20 with status 3
^^^^^^^^^^^^^^^^^
different thread

Worst case scenario looks like that:
[140135346489088] Proceeding call 0x7f73b800a090 with status 0
[140135346489088] Proceeding call 0x7f73a8000b20 with status 1
[140135346489088] Proceeding call 0x7f73a8000b20 with status *2*
[140134984972032] Proceeding call 0x7f73a8000b20 with status *2*
2 different threads modify CallData's status at the same time resulting not 
being freed at all.

What can be done to safely free CallData while getting additional events 
from CompletionQueue after enabling AsyncNotifyWhenDone?

--
Best regards
Przemysław Sobala

-- 
You received this message because you are subscribed to the Google Groups 
"grpc.io" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/grpc-io/c3cd2dd0-e4ae-4514-b44d-419e9b9234ee%40googlegroups.com.

Reply via email to