module Distributed.Failure.Phi (
Phi(..), phi
) where
import Data.Foldable
import Data.List.NonEmpty (NonEmpty)
import Data.Sequence (Seq, (<|))
import qualified Data.Sequence as Seq
import Data.Time
import Distributed.Failure.Class
import Statistics.Distribution
import Statistics.Distribution.Normal
data Phi =
Phi {
_pThresh :: Double
, _pWindow :: Int
, _pLog :: Seq Double
}
deriving (Show, Eq, Ord)
phi :: Double -> Int -> NonEmpty DiffTime -> Phi
phi t w l = Phi t w (Seq.fromList . fmap realToFrac . toList $ l)
instance FailureDetector Phi where
observe (Phi t w l) d = Phi t w (Seq.take w $ (realToFrac d) <| l)
suspected (Phi t _ l) d =
t <= negate (logBase 10 pLater)
where
s = realToFrac . length $ l
m = sum l/s
sd = sqrt $ (sum . fmap (\i -> (i m)^(2::Int)) $ l)/(s1)
esd = if (sd > 0) && (sd < (1/0))
then sd
else if m>0 then m else 1
dist = normalDistr m esd
pLater = complCumulative dist (realToFrac d)