@@ -38,8 +38,8 @@ module Control.Distributed.Process.Internal.Primitives
3838 , unregister
3939 , whereis
4040 , nsend
41− , registerRemote
42− , unregisterRemote
41+ , registerRemoteAsync
42+ , unregisterRemoteAsync
4343 , whereisRemoteAsync
4444 , nsendRemote
4545 -- * Closures
@@ -76,6 +76,7 @@ import Data.Time.Clock (getCurrentTime)
7676import Data.Time.Format (formatTime)
7777import System.Locale (defaultTimeLocale)
7878import System.Timeout (timeout)
79+import Control.Monad (when)
7980import Control.Monad.Reader (ask)
8081import Control.Monad.IO.Class (MonadIO, liftIO)
8182import Control.Applicative ((<$>))
@@ -127,6 +128,8 @@ import Control.Distributed.Process.Internal.Types
127128 , DidUnlinkNode(..)
128129 , DidUnlinkPort(..)
129130 , WhereIsReply(..)
131+ , RegisterReply(..)
132+ , ProcessRegistrationException(..)
130133 , createMessage
131134 , runLocalProcess
132135 , ImplicitReconnect(WithImplicitReconnect, NoImplicitReconnect)
@@ -542,24 +545,44 @@ say string = do
542545--
543546-- The process to be registered does not have to be local itself.
544547register :: String -> ProcessId -> Process ()
545−register label pid =
548+register label pid = do
546549 sendCtrlMsg Nothing (Register label (Just pid))
550+ receiveWait [ matchIf (\(RegisterReply label' _) -> label == label')
551+ (\(RegisterReply _ ok) -> handleRegistrationReply label ok)
552+ ]
547553
548554-- | Register a process with a remote registry (asynchronous).
549555--
550556-- The process to be registered does not have to live on the same remote node.
551−registerRemote :: NodeId -> String -> ProcessId -> Process ()
552−registerRemote nid label pid =
557+-- Reply wil come in the form of a 'RegisterReply' message
558+--
559+-- See comments in 'whereisRemoteAsync'
560+registerRemoteAsync :: NodeId -> String -> ProcessId -> Process ()
561+registerRemoteAsync nid label pid =
553562 sendCtrlMsg (Just nid) (Register label (Just pid))
554563
555564-- | Remove a process from the local registry (asynchronous).
556565unregister :: String -> Process ()
557−unregister label =
566+unregister label = do
558567 sendCtrlMsg Nothing (Register label Nothing)
568+ receiveWait [ matchIf (\(RegisterReply label' _) -> label == label')
569+ (\(RegisterReply _ ok) -> handleRegistrationReply label ok)
570+ ]
571+
572+-- | Deal with the result from an attempted registration or unregistration
573+-- by throwing an exception if necessary
574+handleRegistrationReply :: String -> Bool -> Process ()
575+handleRegistrationReply label ok =
576+ when (not ok) $
577+ liftIO $ throwIO $ ProcessRegistrationException label
559578
560579-- | Remove a process from a remote registry (asynchronous).
561−unregisterRemote :: NodeId -> String -> Process ()
562−unregisterRemote nid label =
580+--
581+-- Reply wil come in the form of a 'RegisterReply' message
582+--
583+-- See comments in 'whereisRemoteAsync'
584+unregisterRemoteAsync :: NodeId -> String -> Process ()
585+unregisterRemoteAsync nid label =
563586 sendCtrlMsg (Just nid) (Register label Nothing)
564587
565588-- | Query the local process registry