Not planned
Description
Hi!
I would like to have a WaitWithTimeout
function in the standard sync/WaitGroup
structure.
Example:
package main
import (
"context"
"log"
"os"
"os/signal"
"sync"
"syscall"
"time"
)
func main() {
wg := &WaitGroupTimeout{}
ctx, cancel := context.WithCancel(context.Background())
var gracefulStopChan = make(chan os.Signal, 1)
signal.Notify(gracefulStopChan, syscall.SIGTERM, syscall.SIGINT)
go func() {
sig := <-gracefulStopChan
log.Printf("Caught sig: %+v\n", sig)
log.Println("Application graceful shutdown begin...")
// Shutdown
cancel()
if ok := wg.WaitWithTimeout(10 * time.Second); !ok {
log.Println("Force shutdown by timeout")
}
log.Println("Application graceful shutdown finished")
os.Exit(1)
}()
log.Println("APP start")
wg.Add(1)
go func() {
defer wg.Done()
for {
select {
case <-ctx.Done():
//time.Sleep(4 * time.Second)
for {
// failed shutdown process or closes something resource
}
log.Println("Break the process 1")
return
case <-time.After(1 * time.Second):
log.Println("Process 1")
}
}
}()
wg.Add(1)
go func() {
defer wg.Done()
for {
select {
case <-ctx.Done():
time.Sleep(5 * time.Second)
log.Println("Break the process 2")
return
case <-time.After(1 * time.Second):
log.Println("Process 2")
}
}
}()
wg.Wait()
}
// I would not like to transfer this code from one project to another
type WaitGroupTimeout struct {
sync.WaitGroup
}
// WaitWithTimeout returns the value "true" when the [WaitGroup] counter is zero.
// And returns the value "false" when the wait is completed by timeout.
func (wg *WaitGroupTimeout) WaitWithTimeout(timeout time.Duration) bool {
timeoutChan := time.After(timeout)
waitChan := make(chan struct{})
go func() {
wg.Wait()
close(waitChan)
}()
select {
case <-timeoutChan:
return false
case <-waitChan:
return true
}
}
Metadata
Metadata
Assignees
Labels
No labels
Activity
gabyhelp commentedon Sep 5, 2024
Related Issues and Documentation
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
seankhliao commentedon Sep 5, 2024
Duplicate of #40916
zigo101 commentedon Sep 5, 2024
It is easy to do this with an additional
time.Timer
.gozoro commentedon Sep 6, 2024
I do this in one line
wg.WaitWithTimeout(10 * time.Second)
. How to put yourtime.Timer
into one function?zigo101 commentedon Sep 6, 2024
Certainly, you can't do it in one line.
Programming with channels is fun, why to lose the fun? :D
I mean it is fun to write the code in your first comment.