From 78f21a8e884d4f673696a844e677381ce8f7a2b7 Mon Sep 17 00:00:00 2001 From: Anton Tiurin Date: Wed, 1 Apr 2015 23:23:43 +0300 Subject: [PATCH] [eventsHandler] Use Lock/Unlock to sync a write access Delete keys from internal maps in a lazy way. The heavy Lock is acquired only when we have errors. Signed-off-by: Anton Tiurin --- api/events.go | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/api/events.go b/api/events.go index cf4a01144c..b586e26b24 100644 --- a/api/events.go +++ b/api/events.go @@ -49,11 +49,12 @@ func (eh *eventsHandler) Handle(e *cluster.Event) error { "time", e.Time, "node", cluster.SerializeNode(e.Node)) + var failed []string + for key, w := range eh.ws { if _, err := fmt.Fprintf(w, str); err != nil { - close(eh.cs[key]) - delete(eh.ws, key) - delete(eh.cs, key) + // collect them to handle later under Lock + failed = append(failed, key) continue } @@ -62,7 +63,24 @@ func (eh *eventsHandler) Handle(e *cluster.Event) error { } } + eh.RUnlock() + + if len(failed) > 0 { + eh.Lock() + + for _, key := range failed { + if ch, ok := eh.cs[key]; ok { + close(ch) + // the maps are expected to have the same keys + delete(eh.cs, key) + delete(eh.ws, key) + } + } + + eh.Unlock() + } + return nil }