{-# LANGUAGE DeriveGeneric, DeriveDataTypeable, MonoLocalBinds #-}

-- |
-- Module     : Simulation.Aivika.Distributed.Optimistic.Guard
-- Copyright  : Copyright (c) 2015-2017, David Sorokin <david.sorokin@gmail.com>
-- License    : BSD3
-- Maintainer : David Sorokin <david.sorokin@gmail.com>
-- Stability  : experimental
-- Tested with: GHC 8.0.2
--
-- This module defines guards that allow correct finishing the distributed simulation.
--
module Simulation.Aivika.Distributed.Optimistic.Guard
       (-- * Guards With Message Passing
        runMasterGuard,
        runSlaveGuard,
        -- * Guards Without Message Passing
        runMasterGuard_,
        runSlaveGuard_)  where

import GHC.Generics

import Data.Typeable
import Data.Binary
import qualified Data.Map as M

import Control.Monad

import qualified Control.Distributed.Process as DP
import Control.Distributed.Process.Serializable

import Simulation.Aivika.Trans
import Simulation.Aivika.Trans.Internal.Types
import Simulation.Aivika.Distributed.Optimistic.Internal.Expect
import Simulation.Aivika.Distributed.Optimistic.DIO
import Simulation.Aivika.Distributed.Optimistic.Message

-- | Represent the master message.
data MasterMessage a = MasterMessage DP.ProcessId (Maybe a)
                     deriving (Int -> MasterMessage a -> ShowS
[MasterMessage a] -> ShowS
MasterMessage a -> String
(Int -> MasterMessage a -> ShowS)
-> (MasterMessage a -> String)
-> ([MasterMessage a] -> ShowS)
-> Show (MasterMessage a)
forall a. Show a => Int -> MasterMessage a -> ShowS
forall a. Show a => [MasterMessage a] -> ShowS
forall a. Show a => MasterMessage a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> MasterMessage a -> ShowS
showsPrec :: Int -> MasterMessage a -> ShowS
$cshow :: forall a. Show a => MasterMessage a -> String
show :: MasterMessage a -> String
$cshowList :: forall a. Show a => [MasterMessage a] -> ShowS
showList :: [MasterMessage a] -> ShowS
Show, Typeable, (forall x. MasterMessage a -> Rep (MasterMessage a) x)
-> (forall x. Rep (MasterMessage a) x -> MasterMessage a)
-> Generic (MasterMessage a)
forall x. Rep (MasterMessage a) x -> MasterMessage a
forall x. MasterMessage a -> Rep (MasterMessage a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (MasterMessage a) x -> MasterMessage a
forall a x. MasterMessage a -> Rep (MasterMessage a) x
$cfrom :: forall a x. MasterMessage a -> Rep (MasterMessage a) x
from :: forall x. MasterMessage a -> Rep (MasterMessage a) x
$cto :: forall a x. Rep (MasterMessage a) x -> MasterMessage a
to :: forall x. Rep (MasterMessage a) x -> MasterMessage a
Generic)

-- | Represent the slave message.
data SlaveMessage a = SlaveMessage DP.ProcessId a
                    deriving (Int -> SlaveMessage a -> ShowS
[SlaveMessage a] -> ShowS
SlaveMessage a -> String
(Int -> SlaveMessage a -> ShowS)
-> (SlaveMessage a -> String)
-> ([SlaveMessage a] -> ShowS)
-> Show (SlaveMessage a)
forall a. Show a => Int -> SlaveMessage a -> ShowS
forall a. Show a => [SlaveMessage a] -> ShowS
forall a. Show a => SlaveMessage a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> SlaveMessage a -> ShowS
showsPrec :: Int -> SlaveMessage a -> ShowS
$cshow :: forall a. Show a => SlaveMessage a -> String
show :: SlaveMessage a -> String
$cshowList :: forall a. Show a => [SlaveMessage a] -> ShowS
showList :: [SlaveMessage a] -> ShowS
Show, Typeable, (forall x. SlaveMessage a -> Rep (SlaveMessage a) x)
-> (forall x. Rep (SlaveMessage a) x -> SlaveMessage a)
-> Generic (SlaveMessage a)
forall x. Rep (SlaveMessage a) x -> SlaveMessage a
forall x. SlaveMessage a -> Rep (SlaveMessage a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (SlaveMessage a) x -> SlaveMessage a
forall a x. SlaveMessage a -> Rep (SlaveMessage a) x
$cfrom :: forall a x. SlaveMessage a -> Rep (SlaveMessage a) x
from :: forall x. SlaveMessage a -> Rep (SlaveMessage a) x
$cto :: forall a x. Rep (SlaveMessage a) x -> SlaveMessage a
to :: forall x. Rep (SlaveMessage a) x -> SlaveMessage a
Generic)
                   
instance Binary a => Binary (MasterMessage a)
instance Binary a => Binary (SlaveMessage a)

-- | Represents the master guard that waits for all slaves to finish.
data MasterGuard a = MasterGuard { forall a. MasterGuard a -> Ref DIO (Map ProcessId a)
masterGuardSlaveMessages :: Ref DIO (M.Map DP.ProcessId a)
                                   -- ^ the messages of slaves connected to the master
                                 }

-- | Represents the slave guard that waits for the master's acknowledgement.
data SlaveGuard a = SlaveGuard { forall a. SlaveGuard a -> Ref DIO (Maybe (Maybe a))
slaveGuardAcknowledgedMessage :: Ref DIO (Maybe (Maybe a))
                                 -- ^ whether the slave process was acknowledged by the master
                               }

-- | Create a new master guard.
newMasterGuard :: Serializable a => Event DIO (MasterGuard a)
newMasterGuard :: forall a. Serializable a => Event DIO (MasterGuard a)
newMasterGuard =
  do Ref DIO (Map ProcessId a)
r <- Simulation DIO (Ref DIO (Map ProcessId a))
-> Event DIO (Ref DIO (Map ProcessId a))
forall a. Simulation DIO a -> Event DIO a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
SimulationLift t m =>
Simulation m a -> t m a
liftSimulation (Simulation DIO (Ref DIO (Map ProcessId a))
 -> Event DIO (Ref DIO (Map ProcessId a)))
-> Simulation DIO (Ref DIO (Map ProcessId a))
-> Event DIO (Ref DIO (Map ProcessId a))
forall a b. (a -> b) -> a -> b
$ Map ProcessId a -> Simulation DIO (Ref DIO (Map ProcessId a))
forall (m :: * -> *) a. MonadDES m => a -> Simulation m (Ref m a)
newRef Map ProcessId a
forall k a. Map k a
M.empty
     Signal DIO (SlaveMessage a)
-> (SlaveMessage a -> Event DIO ())
-> Event DIO (DisposableEvent DIO)
forall (m :: * -> *) a.
Signal m a -> (a -> Event m ()) -> Event m (DisposableEvent m)
handleSignal Signal DIO (SlaveMessage a)
forall a. Serializable a => Signal DIO a
messageReceived ((SlaveMessage a -> Event DIO ())
 -> Event DIO (DisposableEvent DIO))
-> (SlaveMessage a -> Event DIO ())
-> Event DIO (DisposableEvent DIO)
forall a b. (a -> b) -> a -> b
$ \(SlaveMessage ProcessId
slaveId a
a) ->
       Ref DIO (Map ProcessId a)
-> (Map ProcessId a -> Map ProcessId a) -> Event DIO ()
forall (m :: * -> *) a.
MonadDES m =>
Ref m a -> (a -> a) -> Event m ()
modifyRef Ref DIO (Map ProcessId a)
r ((Map ProcessId a -> Map ProcessId a) -> Event DIO ())
-> (Map ProcessId a -> Map ProcessId a) -> Event DIO ()
forall a b. (a -> b) -> a -> b
$ ProcessId -> a -> Map ProcessId a -> Map ProcessId a
forall k a. Ord k => k -> a -> Map k a -> Map k a
M.insert ProcessId
slaveId a
a
     MasterGuard a -> Event DIO (MasterGuard a)
forall a. a -> Event DIO a
forall (m :: * -> *) a. Monad m => a -> m a
return MasterGuard { masterGuardSlaveMessages :: Ref DIO (Map ProcessId a)
masterGuardSlaveMessages = Ref DIO (Map ProcessId a)
r }

-- | Create a new slave guard.
newSlaveGuard :: Serializable a => Event DIO (SlaveGuard a)
newSlaveGuard :: forall a. Serializable a => Event DIO (SlaveGuard a)
newSlaveGuard =
  do Ref DIO (Maybe (Maybe a))
r <- Simulation DIO (Ref DIO (Maybe (Maybe a)))
-> Event DIO (Ref DIO (Maybe (Maybe a)))
forall a. Simulation DIO a -> Event DIO a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
SimulationLift t m =>
Simulation m a -> t m a
liftSimulation (Simulation DIO (Ref DIO (Maybe (Maybe a)))
 -> Event DIO (Ref DIO (Maybe (Maybe a))))
-> Simulation DIO (Ref DIO (Maybe (Maybe a)))
-> Event DIO (Ref DIO (Maybe (Maybe a)))
forall a b. (a -> b) -> a -> b
$ Maybe (Maybe a) -> Simulation DIO (Ref DIO (Maybe (Maybe a)))
forall (m :: * -> *) a. MonadDES m => a -> Simulation m (Ref m a)
newRef Maybe (Maybe a)
forall a. Maybe a
Nothing
     Signal DIO (MasterMessage a)
-> (MasterMessage a -> Event DIO ())
-> Event DIO (DisposableEvent DIO)
forall (m :: * -> *) a.
Signal m a -> (a -> Event m ()) -> Event m (DisposableEvent m)
handleSignal Signal DIO (MasterMessage a)
forall a. Serializable a => Signal DIO a
messageReceived ((MasterMessage a -> Event DIO ())
 -> Event DIO (DisposableEvent DIO))
-> (MasterMessage a -> Event DIO ())
-> Event DIO (DisposableEvent DIO)
forall a b. (a -> b) -> a -> b
$ \(MasterMessage ProcessId
masterId Maybe a
a) ->
       Ref DIO (Maybe (Maybe a)) -> Maybe (Maybe a) -> Event DIO ()
forall (m :: * -> *) a. MonadDES m => Ref m a -> a -> Event m ()
writeRef Ref DIO (Maybe (Maybe a))
r (Maybe a -> Maybe (Maybe a)
forall a. a -> Maybe a
Just Maybe a
a)
     SlaveGuard a -> Event DIO (SlaveGuard a)
forall a. a -> Event DIO a
forall (m :: * -> *) a. Monad m => a -> m a
return SlaveGuard { slaveGuardAcknowledgedMessage :: Ref DIO (Maybe (Maybe a))
slaveGuardAcknowledgedMessage = Ref DIO (Maybe (Maybe a))
r }

-- | Await until the specified number of slaves are connected to the master.
awaitMasterGuard :: Serializable b
                    => MasterGuard a
                    -- ^ the master guard
                    -> Int
                    -- ^ the number of slaves to wait
                    -> (M.Map DP.ProcessId a -> Event DIO (M.Map DP.ProcessId b))
                    -- ^ process the messages sent by slaves
                    -> Process DIO (M.Map DP.ProcessId b)
awaitMasterGuard :: forall b a.
Serializable b =>
MasterGuard a
-> Int
-> (Map ProcessId a -> Event DIO (Map ProcessId b))
-> Process DIO (Map ProcessId b)
awaitMasterGuard MasterGuard a
guard Int
n Map ProcessId a -> Event DIO (Map ProcessId b)
transform =
  Event DIO (Maybe (Map ProcessId b))
-> Process DIO (Map ProcessId b)
forall a. Event DIO (Maybe a) -> Process DIO a
expectProcess (Event DIO (Maybe (Map ProcessId b))
 -> Process DIO (Map ProcessId b))
-> Event DIO (Maybe (Map ProcessId b))
-> Process DIO (Map ProcessId b)
forall a b. (a -> b) -> a -> b
$
  do Map ProcessId a
m <- Ref DIO (Map ProcessId a) -> Event DIO (Map ProcessId a)
forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (Ref DIO (Map ProcessId a) -> Event DIO (Map ProcessId a))
-> Ref DIO (Map ProcessId a) -> Event DIO (Map ProcessId a)
forall a b. (a -> b) -> a -> b
$ MasterGuard a -> Ref DIO (Map ProcessId a)
forall a. MasterGuard a -> Ref DIO (Map ProcessId a)
masterGuardSlaveMessages MasterGuard a
guard
     if Map ProcessId a -> Int
forall k a. Map k a -> Int
M.size Map ProcessId a
m Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
n
       then Maybe (Map ProcessId b) -> Event DIO (Maybe (Map ProcessId b))
forall a. a -> Event DIO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Map ProcessId b)
forall a. Maybe a
Nothing
       else do Map ProcessId b
m' <- Map ProcessId a -> Event DIO (Map ProcessId b)
transform Map ProcessId a
m
               ProcessId
inboxId <- DIO ProcessId -> Event DIO ProcessId
forall a. DIO a -> Event DIO a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
MonadCompTrans t m =>
m a -> t m a
liftComp DIO ProcessId
messageInboxId
               [ProcessId] -> (ProcessId -> Event DIO ()) -> Event DIO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ (Map ProcessId a -> [ProcessId]
forall k a. Map k a -> [k]
M.keys Map ProcessId a
m) ((ProcessId -> Event DIO ()) -> Event DIO ())
-> (ProcessId -> Event DIO ()) -> Event DIO ()
forall a b. (a -> b) -> a -> b
$ \ProcessId
slaveId ->
                 ProcessId -> MasterMessage b -> Event DIO ()
forall a. Serializable a => ProcessId -> a -> Event DIO ()
sendMessage ProcessId
slaveId (ProcessId -> Maybe b -> MasterMessage b
forall a. ProcessId -> Maybe a -> MasterMessage a
MasterMessage ProcessId
inboxId (Maybe b -> MasterMessage b) -> Maybe b -> MasterMessage b
forall a b. (a -> b) -> a -> b
$ ProcessId -> Map ProcessId b -> Maybe b
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup ProcessId
slaveId Map ProcessId b
m')
               Maybe (Map ProcessId b) -> Event DIO (Maybe (Map ProcessId b))
forall a. a -> Event DIO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe (Map ProcessId b) -> Event DIO (Maybe (Map ProcessId b)))
-> Maybe (Map ProcessId b) -> Event DIO (Maybe (Map ProcessId b))
forall a b. (a -> b) -> a -> b
$ Map ProcessId b -> Maybe (Map ProcessId b)
forall a. a -> Maybe a
Just Map ProcessId b
m'

-- | Await until the specified master receives notifications from the slave processes.
awaitSlaveGuard :: (Serializable a,
                    Serializable b)
                   => SlaveGuard a
                   -- ^ the slave guard
                   -> DP.ProcessId
                   -- ^ the master process identifier
                   -> Event DIO b
                   -- ^ the message generator
                   -> Process DIO (Maybe a)
                   -- ^ the master's reply
awaitSlaveGuard :: forall a b.
(Serializable a, Serializable b) =>
SlaveGuard a -> ProcessId -> Event DIO b -> Process DIO (Maybe a)
awaitSlaveGuard SlaveGuard a
guard ProcessId
masterId Event DIO b
generator =
  do Event DIO () -> Process DIO ()
forall a. Event DIO a -> Process DIO a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
EventLift t m =>
Event m a -> t m a
liftEvent (Event DIO () -> Process DIO ()) -> Event DIO () -> Process DIO ()
forall a b. (a -> b) -> a -> b
$
       do b
b <- Event DIO b
generator
          ProcessId
inboxId <- DIO ProcessId -> Event DIO ProcessId
forall a. DIO a -> Event DIO a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
MonadCompTrans t m =>
m a -> t m a
liftComp DIO ProcessId
messageInboxId
          ProcessId -> SlaveMessage b -> Event DIO ()
forall a. Serializable a => ProcessId -> a -> Event DIO ()
sendMessage ProcessId
masterId (ProcessId -> b -> SlaveMessage b
forall a. ProcessId -> a -> SlaveMessage a
SlaveMessage ProcessId
inboxId b
b)
     Event DIO (Maybe (Maybe a)) -> Process DIO (Maybe a)
forall a. Event DIO (Maybe a) -> Process DIO a
expectProcess (Event DIO (Maybe (Maybe a)) -> Process DIO (Maybe a))
-> Event DIO (Maybe (Maybe a)) -> Process DIO (Maybe a)
forall a b. (a -> b) -> a -> b
$
       Ref DIO (Maybe (Maybe a)) -> Event DIO (Maybe (Maybe a))
forall (m :: * -> *) a. MonadDES m => Ref m a -> Event m a
readRef (Ref DIO (Maybe (Maybe a)) -> Event DIO (Maybe (Maybe a)))
-> Ref DIO (Maybe (Maybe a)) -> Event DIO (Maybe (Maybe a))
forall a b. (a -> b) -> a -> b
$ SlaveGuard a -> Ref DIO (Maybe (Maybe a))
forall a. SlaveGuard a -> Ref DIO (Maybe (Maybe a))
slaveGuardAcknowledgedMessage SlaveGuard a
guard

-- | Run the master guard by the specified number of slaves and transform function.
runMasterGuard :: (Serializable a,
                   Serializable b)
                  => Int
                  -- ^ the number of slaves to wait
                  -> (M.Map DP.ProcessId a -> Event DIO (M.Map DP.ProcessId b))
                  -- ^ how to transform the messages from the slave processes in the stop time
                  -> Process DIO (M.Map DP.ProcessId b)
runMasterGuard :: forall a b.
(Serializable a, Serializable b) =>
Int
-> (Map ProcessId a -> Event DIO (Map ProcessId b))
-> Process DIO (Map ProcessId b)
runMasterGuard Int
n Map ProcessId a -> Event DIO (Map ProcessId b)
transform =
  do SignalSource DIO (Map ProcessId b)
source <- Simulation DIO (SignalSource DIO (Map ProcessId b))
-> Process DIO (SignalSource DIO (Map ProcessId b))
forall a. Simulation DIO a -> Process DIO a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
SimulationLift t m =>
Simulation m a -> t m a
liftSimulation Simulation DIO (SignalSource DIO (Map ProcessId b))
forall (m :: * -> *) a.
MonadDES m =>
Simulation m (SignalSource m a)
newSignalSource
     Event DIO () -> Process DIO ()
forall a. Event DIO a -> Process DIO a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
EventLift t m =>
Event m a -> t m a
liftEvent (Event DIO () -> Process DIO ()) -> Event DIO () -> Process DIO ()
forall a b. (a -> b) -> a -> b
$
       do MasterGuard a
guard <- Event DIO (MasterGuard a)
forall a. Serializable a => Event DIO (MasterGuard a)
newMasterGuard
          Event DIO () -> Event DIO ()
forall (m :: * -> *). MonadDES m => Event m () -> Event m ()
enqueueEventWithStopTime (Event DIO () -> Event DIO ()) -> Event DIO () -> Event DIO ()
forall a b. (a -> b) -> a -> b
$
            Process DIO () -> Event DIO ()
forall (m :: * -> *). MonadDES m => Process m () -> Event m ()
runProcess (Process DIO () -> Event DIO ()) -> Process DIO () -> Event DIO ()
forall a b. (a -> b) -> a -> b
$
            do Map ProcessId b
b <- MasterGuard a
-> Int
-> (Map ProcessId a -> Event DIO (Map ProcessId b))
-> Process DIO (Map ProcessId b)
forall b a.
Serializable b =>
MasterGuard a
-> Int
-> (Map ProcessId a -> Event DIO (Map ProcessId b))
-> Process DIO (Map ProcessId b)
awaitMasterGuard MasterGuard a
guard Int
n Map ProcessId a -> Event DIO (Map ProcessId b)
transform
               Event DIO () -> Process DIO ()
forall a. Event DIO a -> Process DIO a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
EventLift t m =>
Event m a -> t m a
liftEvent (Event DIO () -> Process DIO ()) -> Event DIO () -> Process DIO ()
forall a b. (a -> b) -> a -> b
$
                 SignalSource DIO (Map ProcessId b)
-> Map ProcessId b -> Event DIO ()
forall (m :: * -> *) a. SignalSource m a -> a -> Event m ()
triggerSignal SignalSource DIO (Map ProcessId b)
source Map ProcessId b
b
     Signal DIO (Map ProcessId b) -> Process DIO (Map ProcessId b)
forall (m :: * -> *) a. MonadDES m => Signal m a -> Process m a
processAwait (Signal DIO (Map ProcessId b) -> Process DIO (Map ProcessId b))
-> Signal DIO (Map ProcessId b) -> Process DIO (Map ProcessId b)
forall a b. (a -> b) -> a -> b
$ SignalSource DIO (Map ProcessId b) -> Signal DIO (Map ProcessId b)
forall (m :: * -> *) a. SignalSource m a -> Signal m a
publishSignal SignalSource DIO (Map ProcessId b)
source

-- | Run the slave guard by the specified master process identifier and message generator.
runSlaveGuard :: (Serializable a,
                  Serializable b)
                 => DP.ProcessId
                 -- ^ the master process identifier
                 -> Event DIO a
                 -- ^ in the stop time generate a message to pass to the master process
                 -> Process DIO (Maybe b)
                 -- ^ the message returned by the master process
runSlaveGuard :: forall a b.
(Serializable a, Serializable b) =>
ProcessId -> Event DIO a -> Process DIO (Maybe b)
runSlaveGuard ProcessId
masterId Event DIO a
generator =
  do SignalSource DIO (Maybe b)
source <- Simulation DIO (SignalSource DIO (Maybe b))
-> Process DIO (SignalSource DIO (Maybe b))
forall a. Simulation DIO a -> Process DIO a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
SimulationLift t m =>
Simulation m a -> t m a
liftSimulation Simulation DIO (SignalSource DIO (Maybe b))
forall (m :: * -> *) a.
MonadDES m =>
Simulation m (SignalSource m a)
newSignalSource
     Event DIO () -> Process DIO ()
forall a. Event DIO a -> Process DIO a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
EventLift t m =>
Event m a -> t m a
liftEvent (Event DIO () -> Process DIO ()) -> Event DIO () -> Process DIO ()
forall a b. (a -> b) -> a -> b
$
       do SlaveGuard b
guard <- Event DIO (SlaveGuard b)
forall a. Serializable a => Event DIO (SlaveGuard a)
newSlaveGuard
          Event DIO () -> Event DIO ()
forall (m :: * -> *). MonadDES m => Event m () -> Event m ()
enqueueEventWithStopTime (Event DIO () -> Event DIO ()) -> Event DIO () -> Event DIO ()
forall a b. (a -> b) -> a -> b
$
            Process DIO () -> Event DIO ()
forall (m :: * -> *). MonadDES m => Process m () -> Event m ()
runProcess (Process DIO () -> Event DIO ()) -> Process DIO () -> Event DIO ()
forall a b. (a -> b) -> a -> b
$
            do Maybe b
b <- SlaveGuard b -> ProcessId -> Event DIO a -> Process DIO (Maybe b)
forall a b.
(Serializable a, Serializable b) =>
SlaveGuard a -> ProcessId -> Event DIO b -> Process DIO (Maybe a)
awaitSlaveGuard SlaveGuard b
guard ProcessId
masterId Event DIO a
generator
               Event DIO () -> Process DIO ()
forall a. Event DIO a -> Process DIO a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
EventLift t m =>
Event m a -> t m a
liftEvent (Event DIO () -> Process DIO ()) -> Event DIO () -> Process DIO ()
forall a b. (a -> b) -> a -> b
$
                 SignalSource DIO (Maybe b) -> Maybe b -> Event DIO ()
forall (m :: * -> *) a. SignalSource m a -> a -> Event m ()
triggerSignal SignalSource DIO (Maybe b)
source Maybe b
b
     Signal DIO (Maybe b) -> Process DIO (Maybe b)
forall (m :: * -> *) a. MonadDES m => Signal m a -> Process m a
processAwait (Signal DIO (Maybe b) -> Process DIO (Maybe b))
-> Signal DIO (Maybe b) -> Process DIO (Maybe b)
forall a b. (a -> b) -> a -> b
$ SignalSource DIO (Maybe b) -> Signal DIO (Maybe b)
forall (m :: * -> *) a. SignalSource m a -> Signal m a
publishSignal SignalSource DIO (Maybe b)
source

-- | Run the master guard by the specified number of slaves when there is no message passing.
runMasterGuard_ :: Int -> Process DIO ()
runMasterGuard_ :: Int -> Process DIO ()
runMasterGuard_ Int
n =
  do Map ProcessId ()
_ <- Int
-> (Map ProcessId () -> Event DIO (Map ProcessId ()))
-> Process DIO (Map ProcessId ())
forall a b.
(Serializable a, Serializable b) =>
Int
-> (Map ProcessId a -> Event DIO (Map ProcessId b))
-> Process DIO (Map ProcessId b)
runMasterGuard Int
n Map ProcessId () -> Event DIO (Map ProcessId ())
forall {m :: * -> *} {a}. Monad m => a -> m a
transform :: Process DIO (M.Map DP.ProcessId ())
     () -> Process DIO ()
forall a. a -> Process DIO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
       where transform :: a -> m a
transform a
m = a -> m a
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return a
m

-- | Run the slave guard by the specified master process identifier when there is no message passing.
runSlaveGuard_ :: DP.ProcessId -> Process DIO ()
runSlaveGuard_ :: ProcessId -> Process DIO ()
runSlaveGuard_ ProcessId
masterId =
  do Maybe ()
_ <- ProcessId -> Event DIO () -> Process DIO (Maybe ())
forall a b.
(Serializable a, Serializable b) =>
ProcessId -> Event DIO a -> Process DIO (Maybe b)
runSlaveGuard ProcessId
masterId Event DIO ()
generator :: Process DIO (Maybe ())
     () -> Process DIO ()
forall a. a -> Process DIO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()
       where generator :: Event DIO ()
generator = () -> Event DIO ()
forall a. a -> Event DIO a
forall (m :: * -> *) a. Monad m => a -> m a
return ()