distributed-process-extras 0.3.2 → 0.3.5
raw patch · 7 files changed
+80/−51 lines, 7 filesdep ~ansi-terminaldep ~basedep ~distributed-processPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: ansi-terminal, base, distributed-process, distributed-process-systest, network-transport
API changes (from Hackage documentation)
+ Control.Distributed.Process.Extras: checkMonitor :: Monitored a r m => a -> r -> m -> Process Bool
+ Control.Distributed.Process.Extras: class Monitored a r m | a r -> m
+ Control.Distributed.Process.Extras: mkMonitor :: Monitored a r m => a -> Process r
+ Control.Distributed.Process.Extras.Internal.Containers.MultiMap: foldrWithKey :: (k -> v -> a -> a) -> a -> MultiMap k v -> a
+ Control.Distributed.Process.Extras.Internal.Containers.MultiMap: size :: MultiMap k v -> Int
+ Control.Distributed.Process.Extras.Internal.Primitives: checkMonitor :: Monitored a r m => a -> r -> m -> Process Bool
+ Control.Distributed.Process.Extras.Internal.Primitives: class Monitored a r m | a r -> m
+ Control.Distributed.Process.Extras.Internal.Primitives: mkMonitor :: Monitored a r m => a -> Process r
+ Control.Distributed.Process.Extras.Internal.Queue.SeqQ: size :: SeqQ a -> Int
+ Control.Distributed.Process.Extras.Internal.Types: checkMonitor :: Monitored a r m => a -> r -> m -> Process Bool
+ Control.Distributed.Process.Extras.Internal.Types: class Monitored a r m | a r -> m
+ Control.Distributed.Process.Extras.Internal.Types: instance Control.Distributed.Process.Extras.Internal.Types.Resolvable a => Control.Distributed.Process.Extras.Internal.Types.Monitored a Control.Distributed.Process.Internal.Types.MonitorRef Control.Distributed.Process.Internal.Types.ProcessMonitorNotification
+ Control.Distributed.Process.Extras.Internal.Types: mkMonitor :: Monitored a r m => a -> Process r
- Control.Distributed.Process.Extras: class Killable p where killProc r s = resolve r >>= traverse_ (flip kill $ s) exitProc r m = resolve r >>= traverse_ (flip exit $ m)
+ Control.Distributed.Process.Extras: class Killable p
- Control.Distributed.Process.Extras: class Linkable a where linkTo r = resolve r >>= traverse_ link
+ Control.Distributed.Process.Extras: class Linkable a
- Control.Distributed.Process.Extras: class Resolvable a where unresolvableMessage = baseAddressableErrorMessage
+ Control.Distributed.Process.Extras: class Resolvable a
- Control.Distributed.Process.Extras: class Routable a where sendTo a m = do { mPid <- resolve a; maybe (die (unresolvableMessage a)) (\ p -> send p m) mPid } unsafeSendTo a m = do { mPid <- resolve a; maybe (die (unresolvableMessage a)) (\ p -> unsafeSend p $!! m) mPid }
+ Control.Distributed.Process.Extras: class Routable a
- Control.Distributed.Process.Extras: linkTo :: (Linkable a, Resolvable a) => a -> Process ()
+ Control.Distributed.Process.Extras: linkTo :: (Linkable a, (Resolvable a)) => a -> Process ()
- Control.Distributed.Process.Extras: unresolvableMessage :: (Resolvable a, Resolvable a) => a -> String
+ Control.Distributed.Process.Extras: unresolvableMessage :: (Resolvable a, (Resolvable a)) => a -> String
- Control.Distributed.Process.Extras.Internal.Primitives: class Killable p where killProc r s = resolve r >>= traverse_ (flip kill $ s) exitProc r m = resolve r >>= traverse_ (flip exit $ m)
+ Control.Distributed.Process.Extras.Internal.Primitives: class Killable p
- Control.Distributed.Process.Extras.Internal.Primitives: class Linkable a where linkTo r = resolve r >>= traverse_ link
+ Control.Distributed.Process.Extras.Internal.Primitives: class Linkable a
- Control.Distributed.Process.Extras.Internal.Primitives: class Resolvable a where unresolvableMessage = baseAddressableErrorMessage
+ Control.Distributed.Process.Extras.Internal.Primitives: class Resolvable a
- Control.Distributed.Process.Extras.Internal.Primitives: class Routable a where sendTo a m = do { mPid <- resolve a; maybe (die (unresolvableMessage a)) (\ p -> send p m) mPid } unsafeSendTo a m = do { mPid <- resolve a; maybe (die (unresolvableMessage a)) (\ p -> unsafeSend p $!! m) mPid }
+ Control.Distributed.Process.Extras.Internal.Primitives: class Routable a
- Control.Distributed.Process.Extras.Internal.Primitives: linkTo :: (Linkable a, Resolvable a) => a -> Process ()
+ Control.Distributed.Process.Extras.Internal.Primitives: linkTo :: (Linkable a, (Resolvable a)) => a -> Process ()
- Control.Distributed.Process.Extras.Internal.Primitives: unresolvableMessage :: (Resolvable a, Resolvable a) => a -> String
+ Control.Distributed.Process.Extras.Internal.Primitives: unresolvableMessage :: (Resolvable a, (Resolvable a)) => a -> String
- Control.Distributed.Process.Extras.Internal.Types: class Killable p where killProc r s = resolve r >>= traverse_ (flip kill $ s) exitProc r m = resolve r >>= traverse_ (flip exit $ m)
+ Control.Distributed.Process.Extras.Internal.Types: class Killable p
- Control.Distributed.Process.Extras.Internal.Types: class Linkable a where linkTo r = resolve r >>= traverse_ link
+ Control.Distributed.Process.Extras.Internal.Types: class Linkable a
- Control.Distributed.Process.Extras.Internal.Types: class Resolvable a where unresolvableMessage = baseAddressableErrorMessage
+ Control.Distributed.Process.Extras.Internal.Types: class Resolvable a
- Control.Distributed.Process.Extras.Internal.Types: class Routable a where sendTo a m = do { mPid <- resolve a; maybe (die (unresolvableMessage a)) (\ p -> send p m) mPid } unsafeSendTo a m = do { mPid <- resolve a; maybe (die (unresolvableMessage a)) (\ p -> unsafeSend p $!! m) mPid }
+ Control.Distributed.Process.Extras.Internal.Types: class Routable a
- Control.Distributed.Process.Extras.Internal.Types: linkTo :: (Linkable a, Resolvable a) => a -> Process ()
+ Control.Distributed.Process.Extras.Internal.Types: linkTo :: (Linkable a, (Resolvable a)) => a -> Process ()
- Control.Distributed.Process.Extras.Internal.Types: unresolvableMessage :: (Resolvable a, Resolvable a) => a -> String
+ Control.Distributed.Process.Extras.Internal.Types: unresolvableMessage :: (Resolvable a, (Resolvable a)) => a -> String
- Control.Distributed.Process.Extras.SystemLog: class ToLog m where toLog = return . LogData . unsafeWrapMessage
+ Control.Distributed.Process.Extras.SystemLog: class ToLog m
- Control.Distributed.Process.Extras.SystemLog: toLog :: (ToLog m, Serializable m) => m -> Process (LogLevel -> LogMessage)
+ Control.Distributed.Process.Extras.SystemLog: toLog :: (ToLog m, (Serializable m)) => m -> Process (LogLevel -> LogMessage)
Files
- ChangeLog +4/−0
- distributed-process-extras.cabal +18/−19
- src/Control/Distributed/Process/Extras.hs +1/−0
- src/Control/Distributed/Process/Extras/Internal/Containers/MultiMap.hs +9/−2
- src/Control/Distributed/Process/Extras/Internal/Primitives.hs +25/−29
- src/Control/Distributed/Process/Extras/Internal/Queue/SeqQ.hs +7/−1
- src/Control/Distributed/Process/Extras/Internal/Types.hs +16/−0
ChangeLog view
@@ -1,3 +1,7 @@+2017-06-13 Alexander Vershilov <alexander.vershilov@gmail.com> 0.3.5+* Bump dependencies+* Cleanup code+ 2017-02-05 Tim Watson <watson.timothy @ google mail service dot com> 0.3.0 * re-implement whereIsRemote in terms of whereIsRemoteAsync
distributed-process-extras.cabal view
@@ -1,5 +1,5 @@ name: distributed-process-extras-version: 0.3.2+version: 0.3.5 cabal-version: >=1.8 build-type: Simple license: BSD3@@ -8,7 +8,6 @@ Copyright: Tim Watson 2012 - 2017 Author: Tim Watson Maintainer: Tim Watson <watson.timothy@gmail.com>-Stability: experimental Homepage: http://github.com/haskell-distributed/distributed-process-extras Bug-Reports: http://github.com/haskell-distributed/distributed-process-extras/issues synopsis: Cloud Haskell Extras@@ -30,8 +29,8 @@ default: False library- build-depends: base >= 4.6 && < 5,- distributed-process >= 0.6.6 && < 0.7,+ build-depends: base >= 4.8 && < 5,+ distributed-process >= 0.6.0 && < 0.8, binary >= 0.6.3.0 && < 0.9, deepseq >= 1.3.0.1 && < 1.6, mtl >= 2.0 && < 2.4,@@ -71,10 +70,10 @@ x-uses-tf: true build-depends: base >= 4.6 && < 5,- ansi-terminal >= 0.5 && < 0.7,- distributed-process >= 0.6.6 && < 0.7,+ ansi-terminal >= 0.5 && < 0.9,+ distributed-process >= 0.6.0 && < 0.8, distributed-process-extras,- distributed-process-systest >= 0.1.0 && < 0.2.0,+ distributed-process-systest >= 0.1.0 && < 0.3.0, HUnit >= 1.2 && < 2, test-framework >= 0.6 && < 0.9, test-framework-hunit,@@ -94,11 +93,11 @@ x-uses-tf: true build-depends: base >= 4.6 && < 5,- ansi-terminal >= 0.5 && < 0.7,- distributed-process >= 0.6.6 && < 0.7,+ ansi-terminal >= 0.5 && < 0.9,+ distributed-process >= 0.6.0 && < 0.8, distributed-process-extras,- distributed-process-systest >= 0.1.0 && < 0.2.0,- network-transport >= 0.4 && < 0.5,+ distributed-process-systest >= 0.1.0 && < 0.3.0,+ network-transport >= 0.4 && < 0.6, mtl, containers >= 0.4 && < 0.6, network-transport-tcp >= 0.4 && < 0.6,@@ -122,12 +121,12 @@ x-uses-tf: true build-depends: base >= 4.6 && < 5,- ansi-terminal >= 0.5 && < 0.7,+ ansi-terminal >= 0.5 && < 0.9, deepseq >= 1.3.0.1 && < 1.6,- distributed-process >= 0.6.6 && < 0.7,+ distributed-process >= 0.6.0 && < 0.8, distributed-process-extras,- distributed-process-systest >= 0.1.0 && < 0.2.0,- network-transport >= 0.4 && < 0.5,+ distributed-process-systest >= 0.1.0 && < 0.3.0,+ network-transport >= 0.4 && < 0.6, network-transport-tcp >= 0.4 && < 0.6, HUnit >= 1.2 && < 2, test-framework >= 0.6 && < 0.9,@@ -148,18 +147,18 @@ -- x-uses-tf: true build-depends: base >= 4.6 && < 5,- ansi-terminal >= 0.5 && < 0.7,+ ansi-terminal >= 0.5 && < 0.9, containers, hashable, unordered-containers >= 0.2.3.0 && < 0.3,- distributed-process >= 0.6.6 && < 0.7,+ distributed-process >= 0.6.0 && < 0.8, distributed-process-extras,- distributed-process-systest >= 0.1.0 && < 0.2.0,+ distributed-process-systest >= 0.1.0 && < 0.3.0, distributed-static, bytestring, data-accessor, fingertree < 0.2,- network-transport >= 0.4 && < 0.5,+ network-transport >= 0.4 && < 0.6, deepseq >= 1.3.0.1 && < 1.6, mtl, network-transport-tcp >= 0.4 && < 0.6,
src/Control/Distributed/Process/Extras.hs view
@@ -62,6 +62,7 @@ , Routable(..) , Linkable(..) , Killable(..)+ , Monitored(..) , NFSerializable , Recipient(..) , Shutdown(..)
src/Control/Distributed/Process/Extras/Internal/Containers/MultiMap.hs view
@@ -14,7 +14,9 @@ , delete , filter , filterWithKey+ , foldrWithKey , toList+ , size ) where import qualified Data.Foldable as Foldable@@ -46,6 +48,9 @@ empty :: MultiMap k v empty = M $ Map.empty +size :: MultiMap k v -> Int+size = Map.size . hmap+ insert :: forall k v. (Insertable k, Insertable v) => k -> v -> MultiMap k v -> MultiMap k v insert k' v' M{..} =@@ -71,7 +76,8 @@ filter p M{..} = M $ Map.foldlWithKey' (matchOn p) hmap hmap where matchOn pred acc key valueSet =- Map.insert key (Set.filter pred valueSet) acc+ let vs = Set.filter pred valueSet in+ if Set.null vs then acc else Map.insert key vs acc {-# INLINE filter #-} filterWithKey :: forall k v. (Insertable k)@@ -81,7 +87,8 @@ filterWithKey p M{..} = M $ Map.foldlWithKey' (matchOn p) hmap hmap where matchOn pred acc key valueSet =- Map.insert key (Set.filter (pred key) valueSet) acc+ let vs = Set.filter (pred key) valueSet in+ if Set.null vs then acc else Map.insert key vs acc {-# INLINE filterWithKey #-} -- | /O(n)/ Reduce this map by applying a binary operator to all
src/Control/Distributed/Process/Extras/Internal/Primitives.hs view
@@ -27,6 +27,7 @@ , Resolvable(..) , Linkable(..) , Killable(..)+ , Monitored(..) -- * Spawning and Linking , spawnSignalled@@ -57,7 +58,7 @@ import Control.Concurrent (myThreadId, throwTo) import Control.Distributed.Process hiding (monitor, finally, catch)-import qualified Control.Distributed.Process as P (monitor)+import qualified Control.Distributed.Process as P (monitor, unmonitor) import Control.Distributed.Process.Closure (seqCP, remotable, mkClosure) import Control.Distributed.Process.Serializable (Serializable) import Control.Distributed.Process.Extras.Internal.Types@@ -66,52 +67,44 @@ , Killable(..) , Resolvable(..) , Routable(..)+ , Monitored(..) , RegisterSelf(..) , ExitReason(ExitOther) , whereisRemote )-import Control.Monad (void)+import Control.Monad (void, (>=>), replicateM_) import Control.Monad.Catch (finally, catchIf) import Data.Maybe (isJust, fromJust)+import Data.Foldable (traverse_) -- utility -- | Monitor any @Resolvable@ object.--- monitor :: Resolvable a => a -> Process (Maybe MonitorRef)-monitor addr = do- mPid <- resolve addr- case mPid of- Nothing -> return Nothing- Just p -> return . Just =<< P.monitor p+monitor = resolve >=> traverse P.monitor +-- | Wait until @Resolvable@ object will exit. Return immediately+-- if object can't be resolved. awaitExit :: Resolvable a => a -> Process ()-awaitExit addr = do- mPid <- resolve addr- case mPid of- Nothing -> return ()- Just p -> do- mRef <- P.monitor p- receiveWait [- matchIf (\(ProcessMonitorNotification r p' _) -> r == mRef && p == p')- (\_ -> return ())- ]+awaitExit = resolve >=> traverse_ await where+ await pid = withMonitorRef pid $ \ref -> receiveWait+ [ matchIf (\(ProcessMonitorNotification r _ _) -> r == ref)+ (\_ -> return ())+ ]+ withMonitorRef pid = bracket (P.monitor pid) P.unmonitor --- | deliver = flip sendTo+-- | Send message to @Addressable@ object. deliver :: (Addressable a, Serializable m) => m -> a -> Process () deliver = flip sendTo --- | True if getProcessInfo /= Nothing--- NB: only works for local processes.+-- | Check if specified process is alive. Information may be outdated. isProcessAlive :: ProcessId -> Process Bool-isProcessAlive pid = getProcessInfo pid >>= \info -> return $ info /= Nothing+isProcessAlive pid = isJust <$> getProcessInfo pid -- | Apply the supplied expression /n/ times times :: Int -> Process () -> Process ()-n `times` proc = runP proc n- where runP :: Process () -> Int -> Process ()- runP _ 0 = return ()- runP p n' = p >> runP p (n' - 1)+times = replicateM_+{-# DEPRECATED times "use replicateM_ instead" #-} -- | Like 'Control.Monad.forever' but sans space leak forever' :: Monad m => m a -> m b@@ -201,6 +194,8 @@ , matchChan recvStart return ] `finally` (unmonitor mRef) +-- | Helper function will register itself under a given name and send+-- result to given @Process@. registerSelf :: (String, ProcessId) -> Process () registerSelf (name,target) = do self <- getSelfPid@@ -272,9 +267,10 @@ mPid <- resolve addr case mPid of Nothing -> return $ Left $ ExitOther "UnresolvedAddress"- Just p -> do- mRef <- P.monitor p- receiveWait ((matchRef mRef):matches)+ Just p ->+ bracket (P.monitor p)+ P.unmonitor+ $ \mRef -> receiveWait ((matchRef mRef):matches) where matchRef :: MonitorRef -> Match (Either ExitReason b) matchRef r = matchIf (\(ProcessMonitorNotification r' _ _) -> r == r')
src/Control/Distributed/Process/Extras/Internal/Queue/SeqQ.hs view
@@ -8,16 +8,18 @@ , dequeue , peek , filter+ , size ) where -- A simple FIFO queue implementation backed by @Data.Sequence@.-import Prelude hiding (filter)+import Prelude hiding (filter, length) import Data.Sequence ( Seq , ViewR(..) , (<|) , viewr+ , length ) import qualified Data.Sequence as Seq (empty, singleton, null, filter) @@ -49,6 +51,10 @@ {-# INLINE peek #-} peek :: SeqQ a -> Maybe a peek s = maybe Nothing (\(_ :> a) -> Just a) $ getR s++{-# INLINE size #-}+size :: SeqQ a -> Int+size = length . q filter :: (a -> Bool) -> SeqQ a -> SeqQ a filter c s = SeqQ $ Seq.filter c (q s)
src/Control/Distributed/Process/Extras/Internal/Types.hs view
@@ -4,6 +4,8 @@ {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE FunctionalDependencies #-} -- | Types used throughout the Extras package --@@ -18,6 +20,7 @@ , Killable(..) , Resolvable(..) , Routable(..)+ , Monitored(..) , Addressable , Recipient(..) , RegisterSelf(..)@@ -49,6 +52,7 @@ import Control.Monad.Catch (catch) import Data.Binary import Data.Foldable (traverse_)+import Data.Maybe (fromJust) import Data.Typeable (Typeable) import GHC.Generics @@ -144,6 +148,18 @@ -- | Create a /link/ with the supplied object. linkTo :: (Resolvable a) => a -> Process () linkTo r = resolve r >>= traverse_ link++class Monitored a r m | a r -> m where+ mkMonitor :: a -> Process r+ checkMonitor :: a -> r -> m -> Process Bool++instance (Resolvable a) => Monitored a MonitorRef ProcessMonitorNotification where+ mkMonitor a = monitor . fromJust =<< resolve a+ checkMonitor p r (ProcessMonitorNotification ref pid _) = do+ p' <- resolve p+ case p' of+ Nothing -> return False+ Just pr -> return $ ref == r && pid == pr -- | Class of things that can be killed (or instructed to exit). class Killable p where