=rem #3879: Stop sysmsg redelivery for unknown systems after a timeout

This commit is contained in:
Endre Sándor Varga 2014-02-19 11:42:41 +01:00
parent a3b8f51079
commit e69d068cc0
5 changed files with 42 additions and 1 deletions

View file

@ -241,6 +241,7 @@ private[remote] class ReliableDeliverySupervisor(
var writer: ActorRef = createWriter()
var uid: Option[Int] = handleOrActive map { _.handshakeInfo.uid }
val bailoutAt: Deadline = Deadline.now + settings.InitialSysMsgDeliveryTimeout
// Processing of Acks has to be delayed until the UID after a reconnect is discovered. Depending whether the
// UID matches the expected one, pending Acks can be processed, or must be dropped. It is guaranteed that for
// any inbound connections (calling createWriter()) the first message from that connection is GotUid() therefore
@ -321,6 +322,14 @@ private[remote] class ReliableDeliverySupervisor(
context.system.scheduler.scheduleOnce(settings.RetryGateClosedFor, self, Ungate)
case Ungate
if (resendBuffer.nonAcked.nonEmpty || resendBuffer.nacked.nonEmpty) {
// If we talk to a system we have not talked to before (or has given up talking to in the past) stop
// system delivery attempts after the specified time. This act will drop the pending system messages and gate the
// remote address at the EndpointManager level stopping this actor. In case the remote system becomes reachable
// again it will be immediately quarantined due to out-of-sync system message buffer and becomes quarantined.
// In other words, this action is safe.
if (!uidConfirmed && bailoutAt.isOverdue())
throw new InvalidAssociation(localAddress, remoteAddress,
new java.util.concurrent.TimeoutException("Delivery of system messages timed out and they were dropped."))
writer = createWriter()
// Resending will be triggered by the incoming GotUid message after the connection finished
context.become(receive)

View file

@ -78,6 +78,10 @@ final class RemoteSettings(val config: Config) {
getInt("akka.remote.system-message-buffer-size")
} requiring (_ > 0, "system-message-buffer-size must be > 0")
val InitialSysMsgDeliveryTimeout: FiniteDuration = {
config.getMillisDuration("akka.remote.initial-system-message-delivery-timeout")
} requiring (_ > Duration.Zero, "initial-system-message-delivery-timeout must be > 0")
val QuarantineDuration: FiniteDuration = {
config.getMillisDuration("akka.remote.prune-quarantine-marker-after").requiring(_ > Duration.Zero,
"prune-quarantine-marker-after must be > 0 ms")