rendezvous is a Go module that implements a synchronisation mechanism where multiple goroutines must regroup and wait
at a specific point before any of them can proceed.
Since a rendezvous.Point needs to know how many goroutines must be synchronised, we must create one by calling
rendezvous.NewPoint:
point := rendezvous.NewPoint(n)You can also configure the behaviour of an rendezvous.Point by providing some rendezvous.Configurer's to the
rendezvous.NewPoint function. For example:
var locker sync.Locker
// ...
// assign a custom sync.Locker implementation to locker
// ...
point := rendezvous.NewPoint(n, rendezvous.WithLocker(locker))Once you have created a rendezvous.Point, you can call rendezvous.Point.Regroup to ensure that group of goroutines
can only proceed once they have all reached the same point:
var (
wg sync.WaitGroup
point = rendezvous.NewPoint(n)
ctx = context.Background()
)
for i := range n {
wg.Add(1)
go func(i int) {
defer wg.Done()
sleepDuration := rand.N(200 * time.Millisecond)
time.Sleep(sleepDuration)
fmt.Printf("[Goroutine %d] arrived at rendezvous point.\n", i)
err := point.Regroup(ctx)
if err != nil {
fmt.Printf("[Goroutine %d] %s\n", i, err)
return
}
fmt.Printf("[Goroutine %d] regrouped and proceeded.\n", i)
}(i)
}
wg.Wait()
/*
Example output for n = 5:
[Goroutine 4] arrived at rendezvous point.
[Goroutine 0] arrived at rendezvous point.
[Goroutine 1] arrived at rendezvous point.
[Goroutine 2] arrived at rendezvous point.
[Goroutine 3] arrived at rendezvous point.
[Goroutine 3] regrouped and proceeded.
[Goroutine 2] regrouped and proceeded.
[Goroutine 0] regrouped and proceeded.
[Goroutine 1] regrouped and proceeded.
[Goroutine 4] regrouped and proceeded.
*/Documentation for rendezvous can be found here.