Last active
April 2, 2021 19:28
-
-
Save samueleresca/59747f7ddc43f677cd5832dc1e54a22e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import math | |
import time | |
from atomos.atomic import AtomicReference | |
from src._heartbeat_history import _HeartbeatHistory | |
from src._state import _State | |
class PhiAccrualFailureDetector: | |
""" | |
The φ Accrual Failure Detector implementation. | |
See: | |
https://github.com/akka/akka/blob/master/akka-remote/src/main/scala/akka/remote/PhiAccrualFailureDetector.scala | |
""" | |
# ... | |
def _phi(self, timestamp: float) -> float: | |
""" | |
Calculate the φ based on the current state and the timestamp. | |
""" | |
last_state = self._state | |
last_timestamp = last_state.get().timestamp | |
if last_timestamp is None: | |
return 0.0 | |
time_diff = timestamp - last_timestamp | |
last_history = last_state.get().history | |
mean = last_history.mean() | |
std_dev = self._ensure_valid_std_deviation(last_history.std_dev()) | |
return self._calc_phi(time_diff, mean + self.acceptable_heartbeat_pause_ms, std_dev) | |
@classmethod | |
def _calc_phi(cls, time_diff: float, mean: float, std_dev: float) -> float: | |
""" | |
Core method for calculating the phi φ coefficient. It uses a logistic approximation to the cumulative normal | |
distribution. | |
See: https://github.com/akka/akka/issues/1821 | |
""" | |
y = (time_diff - mean) / std_dev | |
try: | |
e = math.exp(-y * (1.5976 + 0.070566 * y * y)) | |
except OverflowError: | |
e = float('inf') | |
if time_diff > mean: | |
return -math.log10(e / (1.0 + e)) | |
else: | |
return -math.log10(1.0 - 1.0 / (1.0 + e)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment