sync.WaitGroup and timeout

661 views
Skip to first unread message

Eugene Toropov

unread,
Jan 1, 2016, 6:14:26 AM1/1/16
to golang-nuts
Greetings,

Happy NY!

I need to implement timeout for the following code:

        var waitSearches sync.WaitGroup

        ...

        // ============================================================================
// wait till all searches completed and close results channel

go func() {
waitSearches.Wait()
close(resultsChannel)
}()


Son once I replace it with:


// ============================================================================
// wait till all searches completed and close results channel

done := make(chan struct{})

go func() {
waitSearches.Wait()
close(done)
}()

select {
case <-done:
close(resultsChannel)
case <-timeoutChannel:
close(resultsChannel)
}

it hangs. Am I doing anything obvious wrong?

Cheers
Eugene

Roberto Zanotto

unread,
Jan 1, 2016, 8:10:21 AM1/1/16
to golang-nuts
If you are using time.After with a proper duration value for your timeout channel, it should be impossible that the select hangs forever.
What are your "searches"? If they are network requests, maybe it would be better to set a deadline on each request, to avoid having request that hang "indefinitely".
I don't see why you are closing both the resultsChannel and a done channel to signal that you are done, one channel should be sufficient...
unless you are delivering items on the resultsChannel, in which case it could be a bad idea to close it on timeout if there are other goroutines that could potentially be writing to it.

o9185...@gmail.com

unread,
Jan 1, 2016, 10:09:50 PM1/1/16
to golang-nuts
Greetings,

Happy NY!

I had the following code:

// ============================================================================
// wait till all searches completed and close results channel

go func() {
waitSearches.Wait()
close(resultsChannel)
}()


replaced it with

// ============================================================================
// wait till all searches completed and close results channel

done := make(chan struct{})

go func() {
waitSearches.Wait()
close(done)
}()

select {
case <-done:
close(resultsChannel)
case <-timeoutChannel:
close(resultsChannel)
}

and now it hangs.

Is there anything obvious wrong in above logic you can see?

Cheers
Eugene

o9185...@gmail.com

unread,
Jan 2, 2016, 3:31:06 AM1/2/16
to golang-nuts
Hi Roberto,

Thanks for your reply and apologize for the duplicate posted after you. It was actually my original post that I sent being signed in into my wife's account (which I didn't notice) - so it said I should wait for 24 hours to see it, so I made 2nd one from my own account and then 1st post was approved and added to the thread.

You're probably right about the deadline which I already have set but for some reason it doesn't always work which I'm going to investigate.

Cheers
Eugene

Roberto Zanotto

unread,
Jan 2, 2016, 7:58:02 AM1/2/16
to golang-nuts, o9185...@gmail.com
Yeah, it's probably the best to make the deadlines work, leaving some goroutines behind that will eventually wake up much later and do stuff could lead to resource leaks and other problems.
If you can't sort it out, share some code to reproduce the issue and hopefully we'll be able to help you more.
Cheers
Reply all
Reply to author
Forward
0 new messages