Handle some corner case states when receiving StartEntity (#29176)
This commit is contained in:
parent
1254595c7d
commit
078d7bd2fb
2 changed files with 199 additions and 10 deletions
|
|
@ -738,21 +738,28 @@ private[akka] class Shard(
|
|||
ackTo.foreach(_ ! ShardRegion.StartEntityAck(entityId, shardId))
|
||||
case _: RememberingStart =>
|
||||
entities.rememberingStart(entityId, ackTo)
|
||||
case RememberedButNotCreated =>
|
||||
// already remembered, just start it - this will be the normal path for initially remembered entities
|
||||
log.debug("Request to start (already remembered) entity [{}]", entityId)
|
||||
case state @ (RememberedButNotCreated | WaitingForRestart) =>
|
||||
// already remembered or waiting for backoff to restart, just start it -
|
||||
// this is the normal path for initially remembered entities getting started
|
||||
log.debug("Request to start entity [{}] (in state [{}])", entityId, state)
|
||||
getOrCreateEntity(entityId)
|
||||
touchLastMessageTimestamp(entityId)
|
||||
ackTo.foreach(_ ! ShardRegion.StartEntityAck(entityId, shardId))
|
||||
case Passivating(_) =>
|
||||
// since StartEntity is handled in deliverMsg we can buffer a StartEntity to handle when
|
||||
// passivation completes (triggering an immediate restart)
|
||||
messageBuffers.append(entityId, ShardRegion.StartEntity(entityId), ackTo.getOrElse(ActorRef.noSender))
|
||||
|
||||
case RememberingStop =>
|
||||
// Optimally: if stop is already write in progress, we want to stash, if it is batched for later write we'd want to cancel
|
||||
// but for now
|
||||
stash()
|
||||
case NoState =>
|
||||
// started manually from the outside, or the shard id extractor was changed since the entity was remembered
|
||||
// we need to store that it was started
|
||||
log.debug("Request to start entity [{}] and ack to [{}]", entityId, ackTo)
|
||||
entities.rememberingStart(entityId, ackTo)
|
||||
rememberUpdate(add = Set(entityId))
|
||||
case other =>
|
||||
// FIXME what do we do here?
|
||||
throw new IllegalStateException(s"Unhandled state when wanting to start $entityId: $other")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -858,8 +865,7 @@ private[akka] class Shard(
|
|||
if (entities.isPassivating(id)) {
|
||||
log.debug("Passivation already in progress for [{}]. Not sending stopMessage back to entity", id)
|
||||
} else if (messageBuffers.getOrEmpty(id).nonEmpty) {
|
||||
log.debug("Passivation when there are buffered messages for [{}], ignoring", id)
|
||||
// FIXME should we buffer the stop message then?
|
||||
log.debug("Passivation when there are buffered messages for [{}], ignoring passivation", id)
|
||||
} else {
|
||||
if (verboseDebug)
|
||||
log.debug("Passivation started for [{}]", id)
|
||||
|
|
@ -924,7 +930,7 @@ private[akka] class Shard(
|
|||
} else {
|
||||
if (verboseDebug)
|
||||
log.debug("StartEntity({}) from [{}], starting", start.entityId, snd)
|
||||
startEntity(start.entityId, Some(sender()))
|
||||
startEntity(start.entityId, Some(snd))
|
||||
}
|
||||
case _ =>
|
||||
entities.entityState(entityId) match {
|
||||
|
|
@ -1010,7 +1016,8 @@ private[akka] class Shard(
|
|||
// Now there is no deliveryBuffer we can try to redeliver
|
||||
// and as the child exists, the message will be directly forwarded
|
||||
messages.foreach {
|
||||
case (msg, snd) => deliverMessage(msg, snd)
|
||||
case (ShardRegion.StartEntity(entityId), snd) => startEntity(entityId, Some(snd))
|
||||
case (msg, snd) => deliverMessage(msg, snd)
|
||||
}
|
||||
touchLastMessageTimestamp(entityId)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue