@@ -2,34 +2,15 @@ package ring
22
33import (
44 "slices"
5- "strconv"
65 "sync"
7-
8- "github.com/buraksezer/consistent"
9- "github.com/cespare/xxhash/v2"
106)
117
12- // xxhashHasher implements the consistent.Hasher interface using xxhash
13- type xxhashHasher struct {}
14-
15- func (h xxhashHasher ) Sum64 (data []byte ) uint64 {
16- return xxhash .Sum64 (data )
17- }
18-
19- // ShardMember implements consistent.Member for shard IDs
20- type ShardMember string
21-
22- func (m ShardMember ) String () string {
23- return string (m )
24- }
25-
268// Store manages shard routing state and workflow mappings
279type Store struct {
28- routingState map [string ]uint32 // workflow_id -> shard_id
29- shardHealth map [uint32 ]bool // shard_id -> is_healthy
30- consistentHash * consistent.Consistent // Consistent hash ring for routing
31- healthyShards []uint32 // Sorted list of healthy shards
32- mu sync.Mutex
10+ routingState map [string ]uint32 // workflow_id -> shard_id
11+ shardHealth map [uint32 ]bool // shard_id -> is_healthy
12+ healthyShards []uint32 // Sorted list of healthy shards
13+ mu sync.Mutex
3314}
3415
3516func NewStore () * Store {
@@ -41,29 +22,15 @@ func NewStore() *Store {
4122 }
4223}
4324
44- // consistentHashConfig returns the configuration for consistent hashing
45- // Matches prototype: PartitionCount=997 (prime), ReplicationFactor=50, Load=1.1
46- func consistentHashConfig () consistent.Config {
47- return consistent.Config {
48- PartitionCount : 997 , // Prime number for better distribution
49- ReplicationFactor : 50 , // Number of replicas per node
50- Load : 1.1 , // Load factor for bounded loads
51- Hasher : xxhashHasher {},
52- }
53- }
54-
55- // updateConsistentHash rebuilds the consistent hash ring based on healthy shards
56- func (s * Store ) updateConsistentHash () {
25+ // updateHealthyShards rebuilds the sorted list of healthy shards
26+ func (s * Store ) updateHealthyShards () {
5727 s .mu .Lock ()
5828 defer s .mu .Unlock ()
5929
60- // Get list of healthy shards and create members
61- healthyMembers := make ([]consistent.Member , 0 )
6230 s .healthyShards = make ([]uint32 , 0 )
6331
6432 for shardID , healthy := range s .shardHealth {
6533 if healthy {
66- healthyMembers = append (healthyMembers , ShardMember (strconv .FormatUint (uint64 (shardID ), 10 )))
6734 s .healthyShards = append (s .healthyShards , shardID )
6835 }
6936 }
@@ -72,39 +39,18 @@ func (s *Store) updateConsistentHash() {
7239 slices .Sort (s .healthyShards )
7340
7441 // If no healthy shards, add shard 0 as fallback
75- if len (healthyMembers ) == 0 {
76- healthyMembers = append (healthyMembers , ShardMember ("0" ))
42+ if len (s .healthyShards ) == 0 {
7743 s .healthyShards = []uint32 {0 }
7844 }
79-
80- // Create consistent hash ring
81- s .consistentHash = consistent .New (healthyMembers , consistentHashConfig ())
8245}
8346
8447// GetShardForWorkflow deterministically assigns a workflow to a shard using consistent hashing.
85- // The assignment uses the same algorithm as the prototype: xxhash + consistent hashing ring.
8648func (s * Store ) GetShardForWorkflow (workflowID string ) uint32 {
8749 s .mu .Lock ()
88- defer s .mu .Unlock ()
89-
90- if s .consistentHash == nil {
91- // Fallback if hash ring not initialized
92- return 0
93- }
94-
95- // Use consistent hashing to find the member for this workflow
96- member := s .consistentHash .LocateKey ([]byte (workflowID ))
97- if member == nil {
98- return 0
99- }
100-
101- // Parse shard ID from member name
102- shardID , err := strconv .ParseUint (member .String (), 10 , 32 )
103- if err != nil {
104- return 0
105- }
50+ shardCount := uint32 (len (s .healthyShards ))
51+ s .mu .Unlock ()
10652
107- return uint32 ( shardID )
53+ return getShardForWorkflow ( workflowID , shardCount )
10854}
10955
11056func (s * Store ) SetShardForWorkflow (workflowID string , shardID uint32 ) {
@@ -128,8 +74,8 @@ func (s *Store) SetShardHealth(shardID uint32, healthy bool) {
12874 s .shardHealth [shardID ] = healthy
12975 s .mu .Unlock ()
13076
131- // Rebuild consistent hash ring when shard health changes
132- s .updateConsistentHash ()
77+ // Rebuild healthy shards list when shard health changes
78+ s .updateHealthyShards ()
13379}
13480
13581func (s * Store ) SetAllShardHealth (health map [uint32 ]bool ) {
@@ -140,8 +86,8 @@ func (s *Store) SetAllShardHealth(health map[uint32]bool) {
14086 }
14187 s .mu .Unlock ()
14288
143- // Rebuild consistent hash ring
144- s .updateConsistentHash ()
89+ // Rebuild healthy shards list
90+ s .updateHealthyShards ()
14591}
14692
14793func (s * Store ) GetAllRoutingState () map [string ]uint32 {
0 commit comments