From 4e69d97376106791112d5c7576d0af9b9e611e39 Mon Sep 17 00:00:00 2001 From: Bryan Boreham Date: Tue, 27 Aug 2019 16:51:15 +0000 Subject: [PATCH] Allow multiple calls to ensureRecalculated() to wait on the same calculation If another call is already waiting, wait on the same chan. This is an improvement on the previous behaviour that only allowed one ensureRecalculated() to proceed per calculate(), in the presence of many recalculate() requests. It is now possible for a later call to overtake the first. Previously it was possible for a later call to overtake an earlier call except for the first. --- routes.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/routes.go b/routes.go index 10ff315..35bed9d 100644 --- a/routes.go +++ b/routes.go @@ -19,7 +19,7 @@ type routes struct { broadcast broadcastRoutes broadcastAll broadcastRoutes // [1] recalc chan<- *struct{} - wait chan<- chan struct{} + wait chan chan struct{} action chan<- func() // [1] based on *all* connections, not just established & // symmetric ones @@ -167,7 +167,13 @@ func (r *routes) recalculate() { // EnsureRecalculated waits for any preceding Recalculate requests to finish. func (r *routes) ensureRecalculated() { - done := make(chan struct{}) + var done chan struct{} + // If another call is already waiting, wait on the same chan, otherwise make a new one + select { + case done = <-r.wait: + default: + done = make(chan struct{}) + } r.wait <- done <-done }