Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

troupe: move non-primitive actions out of Process #37

Merged
merged 1 commit into from
Mar 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 56 additions & 5 deletions troupe/src/Troupe.hs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ module Troupe
where

import Control.Concurrent.STM (atomically, check)
import Control.Monad.IO.Class (MonadIO)
import Data.Typeable (Typeable)
import qualified StmContainers.Map as Map
import Troupe.Exceptions
( Exit (..),
Expand Down Expand Up @@ -101,11 +103,9 @@ import Troupe.Process
WithMonitor (..),
demonitor,
exit,
expect,
getProcessOption,
isProcessAlive,
link,
match,
matchIf,
monitor,
newNodeContext,
Expand All @@ -117,9 +117,6 @@ import Troupe.Process
send,
sendLazy,
setProcessOption,
spawn,
spawnLink,
spawnMonitor,
spawnWithOptions,
unlink,
)
Expand All @@ -145,6 +142,60 @@ runNode r process = do
cnt <- Map.size (nodeContextProcesses nodeContext)
check (cnt == 0)

-- | Spawn a new process.
spawn :: (MonadProcess r m, MonadIO m) => Process r a -> m ProcessId
spawn = spawnWithOptions options
where
options =
SpawnOptions
{ spawnOptionsLink = False,
spawnOptionsMonitor = WithoutMonitor,
spawnOptionsAffinity = Unbound
}
{-# INLINE spawn #-}
{-# SPECIALIZE spawn :: Process r a -> Process r ProcessId #-}

-- | Spawn a new process, and atomically 'link' to it.
--
-- See 'spawn' and 'link'.
spawnLink :: (MonadProcess r m, MonadIO m) => Process r a -> m ProcessId
spawnLink = spawnWithOptions options
where
options =
SpawnOptions
{ spawnOptionsLink = True,
spawnOptionsMonitor = WithoutMonitor,
spawnOptionsAffinity = Unbound
}
{-# INLINE spawnLink #-}
{-# SPECIALIZE spawnLink :: Process r a -> Process r ProcessId #-}

-- | Spawn a new process, and atomically 'monitor' it.
--
-- See 'spawn' and 'monitor'.
spawnMonitor :: (MonadProcess r m, MonadIO m) => Process r a -> m (ProcessId, MonitorRef)
spawnMonitor = spawnWithOptions options
where
options =
SpawnOptions
{ spawnOptionsLink = False,
spawnOptionsMonitor = WithMonitor,
spawnOptionsAffinity = Unbound
}
{-# INLINE spawnMonitor #-}
{-# SPECIALIZE spawnMonitor :: Process r a -> Process r (ProcessId, MonitorRef) #-}

-- | Utility to 'receive' a value of a specific type.
expect :: (MonadProcess r m, MonadIO m, Typeable a) => m a
expect = receive [match pure]
{-# INLINE expect #-}
{-# SPECIALIZE expect :: (Typeable a) => Process r a #-}

-- | Match any message of a specific type.
match :: (Typeable a) => (a -> m b) -> Match m b
match = matchIf (const True)
{-# INLINE match #-}

{-
-- alias
-- cancel_timer
Expand Down
63 changes: 2 additions & 61 deletions troupe/src/Troupe/Process.hs
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@ module Troupe.Process
demonitor,
exit,
isProcessAlive,
spawn,
spawnLink,
spawnMonitor,
spawnWithOptions,
SpawnOptions (..),
ThreadAffinity (..),
Expand All @@ -43,9 +40,7 @@ module Troupe.Process
sendLazy,
receive,
receiveTimeout,
expect,
Match,
match,
matchIf,
)
where
Expand Down Expand Up @@ -586,8 +581,8 @@ data ThreadAffinity

-- | The low-level spawn that takes an additional options argument.
--
-- 'spawn', 'spawnLink' and 'spawnMonitor' are specialized versions of this
-- function.
-- 'Troupe.spawn', 'Troupe.spawnLink' and 'Troupe.spawnMonitor' are specialized
-- versions of this function.
spawnWithOptions :: (MonadProcess r m, MonadIO m) => SpawnOptions t -> Process r a -> m t
spawnWithOptions !options process = do
let cb pid = do
Expand All @@ -602,49 +597,6 @@ spawnWithOptions !options process = do
spawnImpl (spawnOptionsAffinity options) cb process
{-# SPECIALIZE spawnWithOptions :: SpawnOptions t -> Process r a -> Process r t #-}

-- | Spawn a new process.
spawn :: (MonadProcess r m, MonadIO m) => Process r a -> m ProcessId
spawn = spawnWithOptions options
where
options =
SpawnOptions
{ spawnOptionsLink = False,
spawnOptionsMonitor = WithoutMonitor,
spawnOptionsAffinity = Unbound
}
{-# INLINE spawn #-}
{-# SPECIALIZE spawn :: Process r a -> Process r ProcessId #-}

-- | Spawn a new process, and atomically 'link' to it.
--
-- See 'spawn' and 'link'.
spawnLink :: (MonadProcess r m, MonadIO m) => Process r a -> m ProcessId
spawnLink = spawnWithOptions options
where
options =
SpawnOptions
{ spawnOptionsLink = True,
spawnOptionsMonitor = WithoutMonitor,
spawnOptionsAffinity = Unbound
}
{-# INLINE spawnLink #-}
{-# SPECIALIZE spawnLink :: Process r a -> Process r ProcessId #-}

-- | Spawn a new process, and atomically 'monitor' it.
--
-- See 'spawn' and 'monitor'.
spawnMonitor :: (MonadProcess r m, MonadIO m) => Process r a -> m (ProcessId, MonitorRef)
spawnMonitor = spawnWithOptions options
where
options =
SpawnOptions
{ spawnOptionsLink = False,
spawnOptionsMonitor = WithMonitor,
spawnOptionsAffinity = Unbound
}
{-# INLINE spawnMonitor #-}
{-# SPECIALIZE spawnMonitor :: Process r a -> Process r (ProcessId, MonitorRef) #-}

data SendOptions = SendOptions

sendWithOptions :: (MonadProcess r m, MonadIO m, Typeable a) => SendOptions -> ProcessId -> a -> m ()
Expand Down Expand Up @@ -751,17 +703,6 @@ receiveTimeout !t = receiveWithOptions options
{-# INLINE receiveTimeout #-}
{-# SPECIALIZE receiveTimeout :: Int -> [Match (Process r) a] -> Process r (Maybe a) #-}

-- | Utility to 'receive' a value of a specific type.
expect :: (MonadProcess r m, MonadIO m, Typeable a) => m a
expect = receive [match pure]
{-# INLINE expect #-}
{-# SPECIALIZE expect :: (Typeable a) => Process r a #-}

-- | Match any message of a specific type.
match :: (Typeable a) => (a -> m b) -> Match m b
match = matchIf (const True)
{-# INLINE match #-}

-- | Match any message meeting some predicate of a specific type.
matchIf :: (Typeable a) => (a -> Bool) -> (a -> m b) -> Match m b
matchIf predicate handle = MatchMessage $ \dyn -> case fromDynamic dyn of
Expand Down