From 480106bb6eab6c6d920a9a8eafac7bcf018d90eb Mon Sep 17 00:00:00 2001 From: Burak Sezer Date: Wed, 9 Nov 2022 22:51:00 +0300 Subject: [PATCH] fix: eliminate the deadlock issue mentioned in #23 --- consistent.go | 49 +++++++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/consistent.go b/consistent.go index bdd4c63..6725116 100644 --- a/consistent.go +++ b/consistent.go @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2021 Burak Sezer +// Copyright (c) 2018-2022 Burak Sezer // All rights reserved. // // This code is licensed under the MIT License. @@ -26,30 +26,30 @@ // https://research.googleblog.com/2017/04/consistent-hashing-with-bounded-loads.html // // Example Use: -// cfg := consistent.Config{ -// PartitionCount: 71, -// ReplicationFactor: 20, -// Load: 1.25, -// Hasher: hasher{}, -// } // -// // Create a new consistent object -// // You may call this with a list of members -// // instead of adding them one by one. -// c := consistent.New(members, cfg) +// cfg := consistent.Config{ +// PartitionCount: 71, +// ReplicationFactor: 20, +// Load: 1.25, +// Hasher: hasher{}, +// } // -// // myMember struct just needs to implement a String method. -// // New/Add/Remove distributes partitions among members using the algorithm -// // defined on Google Research Blog. -// c.Add(myMember) +// // Create a new consistent object +// // You may call this with a list of members +// // instead of adding them one by one. +// c := consistent.New(members, cfg) // -// key := []byte("my-key") -// // LocateKey hashes the key and calculates partition ID with -// // this modulo operation: MOD(hash result, partition count) -// // The owner of the partition is already calculated by New/Add/Remove. -// // LocateKey just returns the member which's responsible for the key. -// member := c.LocateKey(key) +// // myMember struct just needs to implement a String method. +// // New/Add/Remove distributes partitions among members using the algorithm +// // defined on Google Research Blog. +// c.Add(myMember) // +// key := []byte("my-key") +// // LocateKey hashes the key and calculates partition ID with +// // this modulo operation: MOD(hash result, partition count) +// // The owner of the partition is already calculated by New/Add/Remove. +// // LocateKey just returns the member which's responsible for the key. +// member := c.LocateKey(key) package consistent import ( @@ -285,6 +285,11 @@ func (c *Consistent) GetPartitionOwner(partID int) Member { c.mu.RLock() defer c.mu.RUnlock() + return c.getPartitionOwner(partID) +} + +// getPartitionOwner returns the owner of the given partition. It's not thread-safe. +func (c *Consistent) getPartitionOwner(partID int) Member { member, ok := c.partitions[partID] if !ok { return nil @@ -309,7 +314,7 @@ func (c *Consistent) getClosestN(partID, count int) ([]Member, error) { } var ownerKey uint64 - owner := c.GetPartitionOwner(partID) + owner := c.getPartitionOwner(partID) // Hash and sort all the names. keys := []uint64{} kmems := make(map[uint64]*Member)