org.apache.pekko.remote.DeadlineFailureDetector.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of pekko-remote_2.13 Show documentation
Show all versions of pekko-remote_2.13 Show documentation
Apache Pekko is a toolkit for building highly concurrent, distributed, and resilient message-driven applications for Java and Scala.
The newest version!
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* license agreements; and to You under the Apache License, version 2.0:
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* This file is part of the Apache Pekko project, which was derived from Akka.
*/
/*
* Copyright (C) 2009-2022 Lightbend Inc.
*/
package org.apache.pekko.remote
import scala.concurrent.duration.Duration
import scala.concurrent.duration.FiniteDuration
import com.typesafe.config.Config
import org.apache.pekko
import pekko.event.EventStream
import pekko.remote.FailureDetector.Clock
import pekko.util.Helpers.ConfigOps
/**
* Implementation of failure detector using an absolute timeout of missing heartbeats
* to trigger unavailability.
*
* [[#isAvailable]] will return `false` if there is no [[#heartbeat]] within the duration
* `heartbeatInterval + acceptableHeartbeatPause`.
*
* @param acceptableHeartbeatPause Duration corresponding to number of potentially lost/delayed
* heartbeats that will be accepted before considering it to be an anomaly.
*
* @param heartbeatInterval Expected heartbeat interval
*
* @param clock The clock, returning current time in milliseconds, but can be faked for testing
* purposes. It is only used for measuring intervals (duration).
*/
class DeadlineFailureDetector(val acceptableHeartbeatPause: FiniteDuration, val heartbeatInterval: FiniteDuration)(
implicit
clock: Clock)
extends FailureDetector {
/**
* Constructor that reads parameters from config.
* Expecting config properties named `acceptable-heartbeat-pause`.
*/
def this(config: Config, ev: EventStream) =
this(
acceptableHeartbeatPause = config.getMillisDuration("acceptable-heartbeat-pause"),
heartbeatInterval = config.getMillisDuration("heartbeat-interval"))
require(acceptableHeartbeatPause >= Duration.Zero, "failure-detector.acceptable-heartbeat-pause must be >= 0 s")
require(heartbeatInterval > Duration.Zero, "failure-detector.heartbeat-interval must be > 0 s")
private val deadlineMillis = acceptableHeartbeatPause.toMillis + heartbeatInterval.toMillis
@volatile private var heartbeatTimestamp = 0L // not used until active (first heartbeat)
@volatile private var active = false
override def isAvailable: Boolean = isAvailable(clock())
private def isAvailable(timestamp: Long): Boolean =
if (active) (heartbeatTimestamp + deadlineMillis) > timestamp
else true // treat unmanaged connections, e.g. with zero heartbeats, as healthy connections
override def isMonitoring: Boolean = active
final override def heartbeat(): Unit = {
heartbeatTimestamp = clock()
active = true
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy