From 433ef0790ad72f6d2bef18d3cd5392f8f812d353 Mon Sep 17 00:00:00 2001 From: Steve van Loben Sels Date: Fri, 9 Aug 2019 15:02:00 -0700 Subject: [PATCH] Fixed a data race in the Hash balancer when using custom hasher (#335) --- balancer.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/balancer.go b/balancer.go index 219a61029..c3e8eef40 100644 --- a/balancer.go +++ b/balancer.go @@ -134,6 +134,11 @@ var ( type Hash struct { rr RoundRobin Hasher hash.Hash32 + + // lock protects Hasher while calculating the hash code. It is assumed that + // the Hasher field is read-only once the Balancer is created, so as a + // performance optimization, reads of the field are not protected. + lock sync.Mutex } func (h *Hash) Balance(msg Message, partitions ...int) (partition int) { @@ -142,7 +147,10 @@ func (h *Hash) Balance(msg Message, partitions ...int) (partition int) { } hasher := h.Hasher - if hasher == nil { + if hasher != nil { + h.lock.Lock() + defer h.lock.Unlock() + } else { hasher = fnv1aPool.Get().(hash.Hash32) defer fnv1aPool.Put(hasher) }