Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Transport:Waiting for go routines to exit before closing transport #7666

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

eshitachandwani
Copy link
Member

@eshitachandwani eshitachandwani commented Sep 24, 2024

Fixes: #2869

Previously, clientconn.Close() did not guarantee termination of some go routines upon return.

Now, clientconn.Close() ensures that:

  • It waits for the readerDone channel to signal completion of reader go routine.
  • It waits for the keepAliveDone channel to signal completion of keepAlive go routine.
  • Transports are closed simultaneously, and clientconn.Close() waits for all transports to be closed before returning.

RELEASE NOTES:

  • transport: fixed a bug where the transport was closed before all goroutines had exited.
  • grpc: transports are closed simultaneously, and clientconn.Close() waits for all transports to be closed before returning.

Copy link

codecov bot commented Sep 24, 2024

Codecov Report

Attention: Patch coverage is 93.33333% with 2 lines in your changes missing coverage. Please review.

Project coverage is 81.75%. Comparing base (8ea3460) to head (59ae8aa).
Report is 1 commits behind head on master.

Files with missing lines Patch % Lines
internal/transport/http2_client.go 91.30% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #7666      +/-   ##
==========================================
- Coverage   81.86%   81.75%   -0.11%     
==========================================
  Files         361      361              
  Lines       27821    27838      +17     
==========================================
- Hits        22775    22760      -15     
- Misses       3847     3871      +24     
- Partials     1199     1207       +8     
Files with missing lines Coverage Δ
clientconn.go 92.45% <100.00%> (-0.67%) ⬇️
internal/transport/http2_client.go 92.20% <91.30%> (+0.18%) ⬆️

... and 16 files with indirect coverage changes

for ac := range conns {
ac.tearDown(ErrClientConnClosing)
wg.Add(1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any motivation behind replacing the tear down process with goroutines with sync.WaitGroup? Is this tearDown going to be heavy ops, if not i feel earlier approach might be better? WDYT?

Copy link
Member Author

@eshitachandwani eshitachandwani Sep 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change was suggested by Doug, because now we wait for all go routines inside transport to exit, so it will take time if we serially wait for all transports to close. So we changed it to do the following:
-we will instruct all transports to close simultaneously

  • All the transports will wait for all go routines inside it to exit
  • we wait for all transports to close before exiting
    Instead for asking each transport to close serially , as other transport might not even be signaled to close until all resources in previous transport are cleaned up. Since the transports are not dependent on each other, this approach saves time.

defer func() {
close(t.readerDone)
if errClose != nil {
t.Close(errClose)
Copy link
Contributor

@aranjans aranjans Sep 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't we end up calling t.Close() multiple times in this case? One another instance where we are calling t.Close is this. Thoughts?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I think t.Close() might be called multiple times but it will execute only once always becuase we check the state of the transport beofre actually executing anything, look here ,

if t.state == closing {

And also, t.Close was already being called inside the reader go routine , I just changed it to specifically be called only after the t,readerDone channel is closed, or it was going into infinite wait.

@eshitachandwani eshitachandwani added Area: Transport Includes HTTP/2 client/server and HTTP server handler transports and advanced transport features. and removed Area: Transport Includes HTTP/2 client/server and HTTP server handler transports and advanced transport features. labels Sep 24, 2024
# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ClientConn.Close does not wait for connections to be closed before returning
3 participants