Use tuple to update ConsistentHash and routees together, see #944
This commit is contained in:
parent
5a90d7198c
commit
5c20c07199
1 changed files with 12 additions and 10 deletions
|
|
@ -164,23 +164,25 @@ trait ConsistentHashingLike { this: RouterConfig ⇒
|
|||
if (virtualNodesFactor == 0) routeeProvider.context.system.settings.DefaultVirtualNodesFactor
|
||||
else virtualNodesFactor
|
||||
|
||||
var consistentHashRoutees = new AtomicReference[IndexedSeq[ActorRef]]
|
||||
@volatile var consistentHash: ConsistentHash[ActorRef] = null
|
||||
// tuple of routees and the ConsistentHash, updated together in updateConsistentHash
|
||||
val consistentHashRef = new AtomicReference[(IndexedSeq[ActorRef], ConsistentHash[ActorRef])]((null, null))
|
||||
updateConsistentHash()
|
||||
|
||||
// update consistentHash when routees has changed
|
||||
// changes to routees are rare and when no changes this is a quick operation
|
||||
def updateConsistentHash(): ConsistentHash[ActorRef] = {
|
||||
val currentRoutees = routeeProvider.routees
|
||||
if (currentRoutees ne consistentHashRoutees.get) {
|
||||
val oldConsistentHashRoutees = consistentHashRoutees.get
|
||||
val rehash = currentRoutees != oldConsistentHashRoutees
|
||||
// when other instance, same content, no need to re-hash, but try to set currentRoutees
|
||||
val oldConsistentHashTuple = consistentHashRef.get
|
||||
val (oldConsistentHashRoutees, oldConsistentHash) = oldConsistentHashTuple
|
||||
if (currentRoutees ne oldConsistentHashRoutees) {
|
||||
// when other instance, same content, no need to re-hash, but try to set routees
|
||||
val consistentHash =
|
||||
if (currentRoutees == oldConsistentHashRoutees) oldConsistentHash
|
||||
else ConsistentHash(currentRoutees, vnodes) // re-hash
|
||||
// ignore, don't update, in case of CAS failure
|
||||
if (consistentHashRoutees.compareAndSet(oldConsistentHashRoutees, currentRoutees) && rehash)
|
||||
consistentHash = ConsistentHash(currentRoutees, vnodes)
|
||||
}
|
||||
consistentHash
|
||||
consistentHashRef.compareAndSet(oldConsistentHashTuple, (currentRoutees, consistentHash))
|
||||
consistentHash
|
||||
} else oldConsistentHash
|
||||
}
|
||||
|
||||
def target(hashData: Any): ActorRef = try {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue