Skip to content

Commit

Permalink
Merge pull request #1 from Brijeshlakkad/fix/membership
Browse files Browse the repository at this point in the history
Member leave event with RPC address of the member
  • Loading branch information
Brijeshlakkad committed Aug 23, 2022
2 parents 1a72fd1 + 00d40e6 commit 4681d2a
Show file tree
Hide file tree
Showing 9 changed files with 263 additions and 253 deletions.
23 changes: 11 additions & 12 deletions .vscode/targets.log
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,8 @@ make all --print-data-base --no-builtin-variables --no-builtin-rules --question
# PARTICULAR PURPOSE.

# This program built for i386-apple-darwin11.3.0

make: *** No rule to make target `all'. Stop.


# Make data base, printed on Sun Aug 14 18:42:12 2022
# Make data base, printed on Mon Aug 22 17:02:08 2022

# Variables

Expand Down Expand Up @@ -59,7 +56,7 @@ CONFLUENT_HOME = /Users/brijeshlakkad/confluent
# default
.FEATURES := target-specific order-only second-expansion else-if archives jobserver check-symlink
# environment
SSH_AUTH_SOCK = /private/tmp/com.apple.launchd.wkGlFHQy6Y/Listeners
SSH_AUTH_SOCK = /private/tmp/com.apple.launchd.gMg73kVxfD/Listeners
# automatic
%F = $(notdir $%)
# environment
Expand All @@ -79,7 +76,7 @@ CONFLUENT_CURRENT = /Users/brijeshlakkad/confluent_current
# default
MAKEFILEPATH = $(shell /usr/bin/xcode-select -print-path 2>/dev/null || echo /Developer)/Makefiles
# environment
VSCODE_CODE_CACHE_PATH = /Users/brijeshlakkad/Library/Application Support/Code/CachedData/6d9b74a70ca9c7733b29f0456fd8195364076dda
VSCODE_CODE_CACHE_PATH = /Users/brijeshlakkad/Library/Application Support/Code/CachedData/e4503b30fc78200f846c62cf8091b76ff5547662
# environment
LOGNAME = brijeshlakkad
# environment
Expand Down Expand Up @@ -115,7 +112,7 @@ TMPDIR = /var/folders/l9/pkrn89011n744pxf41ndfjrr0000gn/T/
# automatic
*F = $(notdir $*)
# environment
VSCODE_IPC_HOOK = /Users/brijeshlakkad/Library/Application Support/Code/1.70.1-main.sock
VSCODE_IPC_HOOK = /Users/brijeshlakkad/Library/Application Support/Code/1.70.2-main.sock
# environment
MallocNanoZone = 0
# makefile
Expand All @@ -127,7 +124,7 @@ MFLAGS = -Rrqp
# environment
NVM_DIR = /Users/brijeshlakkad/.nvm
# environment
XPC_SERVICE_NAME = application.com.microsoft.VSCode.85007697.85007703
XPC_SERVICE_NAME = application.com.microsoft.VSCode.85558103.85558109
# environment
HOMEBREW_PREFIX = /opt/homebrew
# automatic
Expand Down Expand Up @@ -163,7 +160,7 @@ LANG = C
# environment
JAVA_8_HOME = /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home
# environment
VSCODE_PID = 1161
VSCODE_PID = 8620
# variable set hash-table stats:
# Load=75/1024=7%, Rehash=0, Collisions=3/99=3%

Expand All @@ -173,9 +170,9 @@ VSCODE_PID = 1161

# Directories

# . (device 16777232, inode 84949235): 18 files, no impossibilities.
# . (device 16777231, inode 84949235): 19 files, no impossibilities.

# 18 files, no impossibilities in 1 directories.
# 19 files, no impossibilities in 1 directories.

# Implicit Rules

Expand Down Expand Up @@ -240,6 +237,8 @@ test:
# strcache size: total = 4096 / max = 4096 / min = 4096 / avg = 4096
# strcache free: total = 4087 / max = 4087 / min = 4087 / avg = 4087

# Finished Make data base on Sun Aug 14 18:42:12 2022
# Finished Make data base on Mon Aug 22 17:02:08 2022


make: *** No rule to make target `all'. Stop.

39 changes: 22 additions & 17 deletions consistent_hash_router.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,38 +9,42 @@ import (
"sync"
)

type ConsistentHashRouter struct {
var (
ErrRealNodeNotFound = errors.New("real node not found")
)

type consistentHashRouter struct {
hashFunction HashFunction
realNodes map[uint64]*ParentNode
realNodes map[uint64]*parentNode
virtualNodes map[uint64]*virtualNode
sortedMap []uint64

lock sync.RWMutex
}

type ParentNode struct {
type parentNode struct {
nodeKey string
virtualNodes map[uint64]*virtualNode
}

func (p *ParentNode) GetKey() string {
func (p *parentNode) GetKey() string {
return p.nodeKey
}

func NewConsistentHashRouter(hashFunction HashFunction) (*ConsistentHashRouter, error) {
func newConsistentHashRouter(hashFunction HashFunction) (*consistentHashRouter, error) {
if hashFunction == nil {
// Default hash function
hashFunction = &MD5HashFunction{}
}
return &ConsistentHashRouter{
return &consistentHashRouter{
hashFunction: hashFunction,
realNodes: map[uint64]*ParentNode{},
realNodes: map[uint64]*parentNode{},
virtualNodes: map[uint64]*virtualNode{},
sortedMap: []uint64{},
}, nil
}

func (c *ConsistentHashRouter) Join(nodeKey string, vNodeCount int) error {
func (c *consistentHashRouter) Join(nodeKey string, vNodeCount int) error {
if vNodeCount < 0 {
return errors.New("virtual node count should be equal or greater than zero")
}
Expand Down Expand Up @@ -69,7 +73,7 @@ func (c *ConsistentHashRouter) Join(nodeKey string, vNodeCount int) error {
return nil
}

func (c *ConsistentHashRouter) Leave(nodeKey string) error {
func (c *consistentHashRouter) Leave(nodeKey string) error {
c.lock.Lock()
defer c.lock.Unlock()

Expand All @@ -92,13 +96,13 @@ func (c *ConsistentHashRouter) Leave(nodeKey string) error {

return nil
}
return errors.New("Real node found!")
return ErrRealNodeNotFound
}

func (c *ConsistentHashRouter) createOrGetParentNode(nodeKey string) *ParentNode {
func (c *consistentHashRouter) createOrGetParentNode(nodeKey string) *parentNode {
pNode, found := c.getParentNode(nodeKey)
if !found {
pNode = &ParentNode{
pNode = &parentNode{
nodeKey: nodeKey,
virtualNodes: map[uint64]*virtualNode{},
}
Expand All @@ -107,15 +111,16 @@ func (c *ConsistentHashRouter) createOrGetParentNode(nodeKey string) *ParentNode
return pNode
}

func (c *ConsistentHashRouter) getParentNode(nodeKey string) (*ParentNode, bool) {
if pNode, ok := c.realNodes[c.hashFunction.hash(nodeKey)]; ok {
func (c *consistentHashRouter) getParentNode(nodeKey string) (*parentNode, bool) {
hash := c.hashFunction.hash(nodeKey)
if pNode, ok := c.realNodes[hash]; ok {
return pNode, true
}
return nil, false
}

// Get clockwise nearest real node based on the key
func (c *ConsistentHashRouter) Get(key string) (interface{}, bool) {
func (c *consistentHashRouter) Get(key string) (interface{}, bool) {
c.lock.RLock()
defer c.lock.RUnlock()

Expand All @@ -139,7 +144,7 @@ func (c *ConsistentHashRouter) Get(key string) (interface{}, bool) {
return c.virtualNodes[c.sortedMap[index]].getRealNode(), true
}

func (c *ConsistentHashRouter) GetVirtualNodes(key string) ([]virtualNode, bool) {
func (c *consistentHashRouter) GetVirtualNodes(key string) ([]virtualNode, bool) {
if pNode, ok := c.realNodes[c.hashFunction.hash(key)]; ok {
var virtualNodes []virtualNode
for _, vNode := range pNode.virtualNodes {
Expand All @@ -152,7 +157,7 @@ func (c *ConsistentHashRouter) GetVirtualNodes(key string) ([]virtualNode, bool)

// virtualNode allows to distribute data across nodes at a finer granularity than can be easily achieved using a single-token architecture.
type virtualNode struct {
parentNode ParentNode
parentNode parentNode
index int
}

Expand Down
55 changes: 31 additions & 24 deletions consistent_hash_router_test.go
Original file line number Diff line number Diff line change
@@ -1,45 +1,52 @@
package ring_test
package ring

import (
"fmt"
"testing"

"github.com/Brijeshlakkad/ring"
"github.com/stretchr/testify/require"
)

const fakeData = "fake_file_name"
const nodeKey0 = "node-0"

func TestLocusManager(t *testing.T) {
for scenario, fn := range map[string]func(
t *testing.T,
){
"create and get": testCreateGetConsistentHashing,
"virtual nodes": testVirtualNode,
"leave node": testLeaveNode,
} {
t.Run(scenario, func(t *testing.T) {
fn(t)
})
}
}

func testCreateGetConsistentHashing(t *testing.T) {
ch, err := ring.NewConsistentHashRouter(nil)
func TestConsistentHashRouter_Get(t *testing.T) {
hashFunction := &MD5HashFunction{}
ch, err := newConsistentHashRouter(hashFunction)
require.NoError(t, err)

var nodeKeys []string

vNodeCount := 0
err = ch.Join(nodeKey0, vNodeCount)
for i := 0; i < 4; i++ {
nodeKey := fmt.Sprintf("node-%d", i)

require.NoError(t, err)
err = ch.Join(nodeKey, vNodeCount)
require.NoError(t, err)

nodeKeys = append(nodeKeys, nodeKey)
}

// We have no virtual nodes
_, found := ch.Get(fakeData)
require.Equal(t, false, found)

vNodeCount = 1
for i := 0; i < 4; i++ {
nodeKey := fmt.Sprintf("node-%d", i)

err = ch.Join(nodeKey, vNodeCount)
require.NoError(t, err)

nodeKeys = append(nodeKeys, nodeKey)
}

_, found = ch.Get(fakeData)
require.Equal(t, true, found)
}

func testVirtualNode(t *testing.T) {
ch, err := ring.NewConsistentHashRouter(nil)
func TestVirtualNode_GetKey(t *testing.T) {
ch, err := newConsistentHashRouter(nil)
require.NoError(t, err)

// 4 virtual nodes
Expand All @@ -57,8 +64,8 @@ func testVirtualNode(t *testing.T) {
require.Equal(t, vNodeCount, len(vNodes))
}

func testLeaveNode(t *testing.T) {
ch, err := ring.NewConsistentHashRouter(nil)
func TestConsistentHashRouter_Leave(t *testing.T) {
ch, err := newConsistentHashRouter(nil)
require.NoError(t, err)

// 1 virtual nodes
Expand Down
12 changes: 4 additions & 8 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,18 @@ module github.com/Brijeshlakkad/ring
go 1.17

require (
github.com/hashicorp/go-hclog v1.2.2
github.com/hashicorp/serf v0.10.0
github.com/soheilhy/cmux v0.1.5
github.com/stretchr/testify v1.8.0
github.com/travisjeffery/go-dynaport v1.0.0
github.com/umpc/go-sortedmap v0.0.0-20180422175548-64ab94c482f4
go.uber.org/zap v1.22.0
google.golang.org/grpc v1.48.0
)

require (
github.com/armon/go-metrics v0.3.10 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/fatih/color v1.13.0 // indirect
github.com/google/btree v1.0.0 // indirect
github.com/google/go-cmp v0.5.8 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/go-msgpack v0.5.5 // indirect
Expand All @@ -26,6 +23,8 @@ require (
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/hashicorp/memberlist v0.4.0 // indirect
github.com/kr/pretty v0.3.0 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/miekg/dns v1.1.41 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
Expand All @@ -35,8 +34,5 @@ require (
golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2 // indirect
golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 // indirect
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 // indirect
golang.org/x/text v0.3.7 // indirect
google.golang.org/genproto v0.0.0-20220708155623-50e5f4832e73 // indirect
google.golang.org/protobuf v1.28.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading

0 comments on commit 4681d2a

Please sign in to comment.