Hi,
I am using a callback based server (ServerWriteReactor) with streaming and a callback based client (ClientReadReactor).
Client reads streamed messages from the server but at some point it cancels the stream using context.TryCancel() from a separate thread. It then waits for the final OnDone() callback.
So a simplified sequence might look like:
<- OnReadInitialMetadataDone()
<- OnReadDone (ok=true)
<- OnReadDone (ok=true)
...
-> TryCancel()
...
<- OnReadDone (ok=true)
<- OnReadDone (ok=false)
<- OnDone()
After OnDone(), within the context of the TryCancel() thread, client's Chanel & Stub are destroyed..
Once in a while (regression tests repeat the above in a loop) during destruction of Channel/Stub, the code hangs for ~10sec (garbage collection timeout for other environments waiting for resources to be released ?) i get the leaks:
D0401 iomgr.cc:138] Failed to free 1 iomgr objects before shutdown deadline: memory leaks are likely
D0401 iomgr.cc:87] LEAKED OBJECT: client:socket=0x0x13f7cc8 013F7D34
E0401 10:12:21.792000000 2180 metadata.cc:253] WARNING: 1 metadata elements were leaked
E0401 10:12:21.792000000 2180 metadata.cc:260] mdelem 'user-agent' = 'grpc-c++/1.42.0 grpc-c/20.0.0 (windows; chttp2)'
E0401 10:12:21.792000000 2180 metadata.cc:253] WARNING: 1 metadata elements were leaked
E0401 10:12:21.792000000 2180 metadata.cc:260] mdelem ':authority' = 'localhost:8008'
D0401 10:12:21.792000000 2180 slice_intern.cc:350] WARNING: 1 metadata strings were leaked
D0401 10:12:21.792000000 2180 slice_intern.cc:356] LEAKED: 67 72 70 63 2d 63 2b 2b 2f 31 2e 34 32 2e 30 20 67 72 70 63 2d 63 2f 32 30 2e 30 2e 30 20 28 77 69 6e 64 6f 77 73 3b 20 63 68 74 74 70 32 29 'grpc-c++/1.42.0 grpc-c/20.0.0 (windows; chttp2)'
D0401 10:12:21.792000000 2180 slice_intern.cc:350] WARNING: 1 metadata strings were leaked
D0401 10:12:21.792000000 2180 slice_intern.cc:356] LEAKED: 6c 6f 63 61 6c 68 6f 73 74 3a 38 30 30 38 'localhost:8008'
I am using Window 10, both 32/64 bit clients, gRPC 1.42.0
Any clues on how to avoid the leaks ? They originate in the core library code - I do not have control over reference counters holding on to the socket.
Thanks.