{-# LANGUAGE DeriveDataTypeable #-} module MathsDemo ( add , divide , launchMathServer , DivByZero(..) , Add(..) ) where import Control.Distributed.Process hiding (call) import Control.Distributed.Process.Extras import Control.Distributed.Process.Extras.Time import Control.Distributed.Process.ManagedProcess import Data.Binary (Binary(..)) import Data.Typeable (Typeable) data Add = Add Double Double deriving (Typeable) data Divide = Divide Double Double deriving (Typeable) data DivByZero = DivByZero deriving (Typeable, Eq) instance Binary Add where put (Add x y) = put x >> put y get = Add <$> get <*> get instance Binary Divide where put (Divide x y) = put x >> put y get = Divide <$> get <*> get instance Binary DivByZero where put DivByZero = return () get = return DivByZero -- public API add :: ProcessId -> Double -> Double -> Process Double add sid x y = call sid (Add x y) divide :: ProcessId -> Double -> Double -> Process (Either DivByZero Double) divide sid x y = call sid (Divide x y ) launchMathServer :: Process ProcessId launchMathServer = let server = statelessProcess { apiHandlers = [ handleCall_ (\(Add x y) -> return (x + y)) , handleCallIf_ (input (\(Divide _ y) -> y /= 0)) handleDivide , handleCall_ (\(Divide _ _) -> divByZero) , action (\("stop") -> stop_ ExitNormal) ] } in spawnLocal $ serve () (statelessInit Infinity) server where handleDivide :: Divide -> Process (Either DivByZero Double) handleDivide (Divide x y) = return $ Right $ x / y divByZero :: Process (Either DivByZero Double) divByZero = return $ Left DivByZero