distributed-process-client-server 0.2.0 → 0.2.1
raw patch · 6 files changed
+190/−9 lines, 6 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
+ Control.Distributed.Process.ManagedProcess.Internal.GenProcess: act :: forall s. GenProcess s () -> Action s
+ Control.Distributed.Process.ManagedProcess.Internal.GenProcess: addUserTimer :: Timer -> Message -> GenProcess s TimerKey
+ Control.Distributed.Process.ManagedProcess.Internal.GenProcess: currentTimeout :: GenProcess s Delay
+ Control.Distributed.Process.ManagedProcess.Internal.GenProcess: data GenProcess s a
+ Control.Distributed.Process.ManagedProcess.Internal.GenProcess: drainTimeout :: GenProcess s Delay
+ Control.Distributed.Process.ManagedProcess.Internal.GenProcess: enqueue :: forall s. Message -> GenProcess s ()
+ Control.Distributed.Process.ManagedProcess.Internal.GenProcess: evalAfter :: forall s m. (Serializable m) => TimeInterval -> m -> s -> Action s
+ Control.Distributed.Process.ManagedProcess.Internal.GenProcess: getAndModifyState :: (ProcessState s -> (ProcessState s, a)) -> GenProcess s a
+ Control.Distributed.Process.ManagedProcess.Internal.GenProcess: gets :: forall s a. (ProcessState s -> a) -> GenProcess s a
+ Control.Distributed.Process.ManagedProcess.Internal.GenProcess: instance Control.Distributed.Process.ManagedProcess.Internal.GenProcess.DynFilterHandler Control.Distributed.Process.ManagedProcess.Internal.Types.DispatchFilter
+ Control.Distributed.Process.ManagedProcess.Internal.GenProcess: instance Control.Distributed.Process.ManagedProcess.Internal.GenProcess.DynMessageHandler Control.Distributed.Process.ManagedProcess.Internal.Types.DeferredDispatcher
+ Control.Distributed.Process.ManagedProcess.Internal.GenProcess: instance Control.Distributed.Process.ManagedProcess.Internal.GenProcess.DynMessageHandler Control.Distributed.Process.ManagedProcess.Internal.Types.Dispatcher
+ Control.Distributed.Process.ManagedProcess.Internal.GenProcess: instance Control.Distributed.Process.ManagedProcess.Internal.GenProcess.DynMessageHandler Control.Distributed.Process.ManagedProcess.Internal.Types.ExternDispatcher
+ Control.Distributed.Process.ManagedProcess.Internal.GenProcess: modifyState :: (ProcessState s -> ProcessState s) -> GenProcess s ()
+ Control.Distributed.Process.ManagedProcess.Internal.GenProcess: peek :: GenProcess s (Maybe Message)
+ Control.Distributed.Process.ManagedProcess.Internal.GenProcess: precvLoop :: PrioritisedProcessDefinition s -> s -> Delay -> Process ExitReason
+ Control.Distributed.Process.ManagedProcess.Internal.GenProcess: processDefinition :: GenProcess s (ProcessDefinition s)
+ Control.Distributed.Process.ManagedProcess.Internal.GenProcess: processFilters :: GenProcess s ([DispatchFilter s])
+ Control.Distributed.Process.ManagedProcess.Internal.GenProcess: processState :: GenProcess s s
+ Control.Distributed.Process.ManagedProcess.Internal.GenProcess: processUnhandledMsgPolicy :: GenProcess s UnhandledMessagePolicy
+ Control.Distributed.Process.ManagedProcess.Internal.GenProcess: push :: forall s. Message -> GenProcess s ()
+ Control.Distributed.Process.ManagedProcess.Internal.GenProcess: recvLoop :: ProcessDefinition s -> s -> Delay -> Process ExitReason
+ Control.Distributed.Process.ManagedProcess.Internal.GenProcess: removeUserTimer :: TimerKey -> GenProcess s ()
+ Control.Distributed.Process.ManagedProcess.Internal.GenProcess: runAfter :: forall s m. (Serializable m) => TimeInterval -> m -> GenProcess s ()
+ Control.Distributed.Process.ManagedProcess.Internal.GenProcess: setProcessState :: s -> GenProcess s ()
+ Control.Distributed.Process.ManagedProcess.Internal.GenProcess: setUserTimeout :: Delay -> GenProcess s ()
+ Control.Distributed.Process.ManagedProcess.Internal.GenProcess: systemTimeout :: GenProcess s Timer
+ Control.Distributed.Process.ManagedProcess.Internal.Types: CallMessage :: a -> (CallRef b) -> Message a b
+ Control.Distributed.Process.ManagedProcess.Internal.Types: CallRef :: (Recipient, CallId) -> CallRef a
+ Control.Distributed.Process.ManagedProcess.Internal.Types: CallRejected :: String -> CallId -> CallRejected
+ Control.Distributed.Process.ManagedProcess.Internal.Types: CallResponse :: a -> CallId -> CallResponse a
+ Control.Distributed.Process.ManagedProcess.Internal.Types: CastMessage :: a -> Message a b
+ Control.Distributed.Process.ManagedProcess.Internal.Types: ChanMessage :: a -> (SendPort b) -> Message a b
+ Control.Distributed.Process.ManagedProcess.Internal.Types: CleanShutdown :: s -> ExitState s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: Condition :: (s -> m -> Bool) -> Condition s m
+ Control.Distributed.Process.ManagedProcess.Internal.Types: ControlChannel :: (SendPort (Message m ()), ReceivePort (Message m ())) -> ControlChannel m
+ Control.Distributed.Process.ManagedProcess.Internal.Types: ControlPort :: SendPort (Message m ()) -> ControlPort m
+ Control.Distributed.Process.ManagedProcess.Internal.Types: DeadLetter :: ProcessId -> UnhandledMessagePolicy
+ Control.Distributed.Process.ManagedProcess.Internal.Types: DeferredDispatcher :: (s -> Message -> Process (Maybe (ProcessAction s))) -> DeferredDispatcher s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: Dispatch :: (s -> Message a b -> Process (ProcessAction s)) -> Dispatcher s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: DispatchCC :: ReceivePort (Message a b) -> (s -> Message a b -> Process (ProcessAction s)) -> ExternDispatcher s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: DispatchIf :: (s -> Message a b -> Process (ProcessAction s)) -> (s -> Message a b -> Bool) -> Dispatcher s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: DispatchSTM :: STM a -> (s -> a -> Process (ProcessAction s)) -> Match Message -> (forall m. (Message -> m) -> Match m) -> ExternDispatcher s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: Drop :: UnhandledMessagePolicy
+ Control.Distributed.Process.ManagedProcess.Internal.Types: ExitSignalDispatcher :: (s -> ProcessId -> Message -> Process (Maybe (ProcessAction s))) -> ExitSignalDispatcher s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: FilterAny :: (s -> a -> Process (Filter s)) -> DispatchFilter s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: FilterApi :: (s -> Message a b -> Process (Filter s)) -> DispatchFilter s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: FilterOk :: s -> Filter s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: FilterRaw :: (s -> Message -> Process (Maybe (Filter s))) -> DispatchFilter s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: FilterReject :: m -> s -> Filter s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: FilterSafe :: s -> Filter s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: FilterSkip :: s -> Filter s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: FilterState :: (s -> Process (Maybe (Filter s))) -> DispatchFilter s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: FilterStop :: s -> ExitReason -> Filter s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: InitIgnore :: InitResult s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: InitOk :: s -> Delay -> InitResult s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: InitStop :: String -> InitResult s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: Input :: (m -> Bool) -> Condition s m
+ Control.Distributed.Process.ManagedProcess.Internal.Types: LastKnown :: s -> ExitState s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: Log :: UnhandledMessagePolicy
+ Control.Distributed.Process.ManagedProcess.Internal.Types: NoReply :: (ProcessAction s) -> ProcessReply r s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: PrioritiseCall :: (s -> Message -> Process (Maybe (Int, Message))) -> DispatchPriority s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: PrioritiseCast :: (s -> Message -> Process (Maybe (Int, Message))) -> DispatchPriority s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: PrioritiseInfo :: (s -> Message -> Process (Maybe (Int, Message))) -> DispatchPriority s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: PrioritisedProcessDefinition :: ProcessDefinition s -> [DispatchPriority s] -> [DispatchFilter s] -> RecvTimeoutPolicy -> PrioritisedProcessDefinition s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: Priority :: Int -> Priority a
+ Control.Distributed.Process.ManagedProcess.Internal.Types: ProcessActivity :: (GenProcess s ()) -> ProcessAction s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: ProcessBecome :: (ProcessDefinition s) -> s -> ProcessAction s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: ProcessContinue :: s -> ProcessAction s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: ProcessDefinition :: [Dispatcher s] -> [DeferredDispatcher s] -> [ExternDispatcher s] -> [ExitSignalDispatcher s] -> TimeoutHandler s -> ShutdownHandler s -> UnhandledMessagePolicy -> ProcessDefinition s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: ProcessHibernate :: TimeInterval -> s -> ProcessAction s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: ProcessReject :: String -> (ProcessAction s) -> ProcessReply r s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: ProcessReply :: r -> (ProcessAction s) -> ProcessReply r s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: ProcessSkip :: ProcessAction s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: ProcessState :: RecvTimeoutPolicy -> ProcessDefinition s -> [DispatchPriority s] -> [DispatchFilter s] -> Delay -> Timer -> TimerMap -> Queue -> s -> ProcessState s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: ProcessStop :: ExitReason -> ProcessAction s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: ProcessStopping :: s -> ExitReason -> ProcessAction s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: ProcessTimeout :: Delay -> s -> ProcessAction s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: RecvMaxBacklog :: Int -> RecvTimeoutPolicy
+ Control.Distributed.Process.ManagedProcess.Internal.Types: RecvTimer :: TimeInterval -> RecvTimeoutPolicy
+ Control.Distributed.Process.ManagedProcess.Internal.Types: State :: (s -> Bool) -> Condition s m
+ Control.Distributed.Process.ManagedProcess.Internal.Types: Terminate :: UnhandledMessagePolicy
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [anyFilter] :: DispatchFilter s -> s -> a -> Process (Filter s)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [apiFilter] :: DispatchFilter s -> s -> Message a b -> Process (Filter s)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [apiHandlers] :: ProcessDefinition s -> [Dispatcher s]
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [channel] :: ExternDispatcher s -> ReceivePort (Message a b)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [dispatchChan] :: ExternDispatcher s -> s -> Message a b -> Process (ProcessAction s)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [dispatchExit] :: ExitSignalDispatcher s -> s -> ProcessId -> Message -> Process (Maybe (ProcessAction s))
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [dispatchIf] :: Dispatcher s -> s -> Message a b -> Bool
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [dispatchInfo] :: DeferredDispatcher s -> s -> Message -> Process (Maybe (ProcessAction s))
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [dispatchStm] :: ExternDispatcher s -> s -> a -> Process (ProcessAction s)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [dispatch] :: Dispatcher s -> s -> Message a b -> Process (ProcessAction s)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [exitHandlers] :: ProcessDefinition s -> [ExitSignalDispatcher s]
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [externHandlers] :: ProcessDefinition s -> [ExternDispatcher s]
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [filters] :: PrioritisedProcessDefinition s -> [DispatchFilter s]
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [getPrio] :: Priority a -> Int
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [infoHandlers] :: ProcessDefinition s -> [DeferredDispatcher s]
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [internalQ] :: ProcessState s -> Queue
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [matchAnyStm] :: ExternDispatcher s -> forall m. (Message -> m) -> Match m
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [matchStm] :: ExternDispatcher s -> Match Message
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [priorities] :: PrioritisedProcessDefinition s -> [DispatchPriority s]
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [prioritise] :: DispatchPriority s -> s -> Message -> Process (Maybe (Int, Message))
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [procDef] :: ProcessState s -> ProcessDefinition s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [procFilters] :: ProcessState s -> [DispatchFilter s]
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [procPrio] :: ProcessState s -> [DispatchPriority s]
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [procState] :: ProcessState s -> s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [processDef] :: PrioritisedProcessDefinition s -> ProcessDefinition s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [rawFilter] :: DispatchFilter s -> s -> Message -> Process (Maybe (Filter s))
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [recvTimeout] :: PrioritisedProcessDefinition s -> RecvTimeoutPolicy
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [shutdownHandler] :: ProcessDefinition s -> ShutdownHandler s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [stateFilter] :: DispatchFilter s -> s -> Process (Maybe (Filter s))
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [stmAction] :: ExternDispatcher s -> STM a
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [sysTimeout] :: ProcessState s -> Timer
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [timeoutHandler] :: ProcessDefinition s -> TimeoutHandler s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [timeoutSpec] :: ProcessState s -> RecvTimeoutPolicy
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [unCaller] :: CallRef a -> (Recipient, CallId)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [unControl] :: ControlChannel m -> (SendPort (Message m ()), ReceivePort (Message m ()))
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [unPort] :: ControlPort m -> SendPort (Message m ())
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [unhandledMessagePolicy] :: ProcessDefinition s -> UnhandledMessagePolicy
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [usrTimeout] :: ProcessState s -> Delay
+ Control.Distributed.Process.ManagedProcess.Internal.Types: [usrTimers] :: ProcessState s -> TimerMap
+ Control.Distributed.Process.ManagedProcess.Internal.Types: caller :: forall a b. Message a b -> Maybe Recipient
+ Control.Distributed.Process.ManagedProcess.Internal.Types: channelControlPort :: ControlChannel m -> ControlPort m
+ Control.Distributed.Process.ManagedProcess.Internal.Types: class ExternMatcher d
+ Control.Distributed.Process.ManagedProcess.Internal.Types: class MessageMatcher d
+ Control.Distributed.Process.ManagedProcess.Internal.Types: data CallRejected
+ Control.Distributed.Process.ManagedProcess.Internal.Types: data CallResponse a
+ Control.Distributed.Process.ManagedProcess.Internal.Types: data Condition s m
+ Control.Distributed.Process.ManagedProcess.Internal.Types: data DeferredDispatcher s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: data DispatchFilter s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: data DispatchPriority s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: data Dispatcher s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: data ExitSignalDispatcher s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: data ExitState s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: data ExternDispatcher s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: data Filter s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: data GenProcess s a
+ Control.Distributed.Process.ManagedProcess.Internal.Types: data InitResult s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: data Message a b
+ Control.Distributed.Process.ManagedProcess.Internal.Types: data PrioritisedProcessDefinition s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: data ProcessAction s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: data ProcessDefinition s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: data ProcessReply r s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: data ProcessState s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: data RecvTimeoutPolicy
+ Control.Distributed.Process.ManagedProcess.Internal.Types: data UnhandledMessagePolicy
+ Control.Distributed.Process.ManagedProcess.Internal.Types: exitState :: ExitState s -> s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: initCall :: forall s a b. (Addressable s, Serializable a, Serializable b) => s -> a -> Process (CallRef b)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance (Control.Distributed.Process.Extras.Internal.Types.NFSerializable a, Control.Distributed.Process.Extras.Internal.Types.NFSerializable b) => Control.DeepSeq.NFData (Control.Distributed.Process.ManagedProcess.Internal.Types.Message a b)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance (Control.Distributed.Process.Serializable.Serializable a, Control.Distributed.Process.Serializable.Serializable b) => Data.Binary.Class.Binary (Control.Distributed.Process.ManagedProcess.Internal.Types.Message a b)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance (GHC.Classes.Eq a, GHC.Classes.Eq b) => GHC.Classes.Eq (Control.Distributed.Process.ManagedProcess.Internal.Types.Message a b)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance (GHC.Show.Show a, GHC.Show.Show b) => GHC.Show.Show (Control.Distributed.Process.ManagedProcess.Internal.Types.Message a b)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance Control.DeepSeq.NFData (Control.Distributed.Process.ManagedProcess.Internal.Types.CallRef a)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance Control.DeepSeq.NFData Control.Distributed.Process.ManagedProcess.Internal.Types.CallRejected
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance Control.Distributed.Process.Extras.Internal.Types.NFSerializable a => Control.DeepSeq.NFData (Control.Distributed.Process.ManagedProcess.Internal.Types.CallResponse a)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance Control.Distributed.Process.Extras.Internal.Types.Resolvable (Control.Distributed.Process.ManagedProcess.Internal.Types.CallRef a)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance Control.Distributed.Process.Extras.Internal.Types.Routable (Control.Distributed.Process.ManagedProcess.Internal.Types.CallRef a)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance Control.Distributed.Process.ManagedProcess.Internal.Types.ExternMatcher Control.Distributed.Process.ManagedProcess.Internal.Types.ExternDispatcher
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance Control.Distributed.Process.ManagedProcess.Internal.Types.MessageMatcher Control.Distributed.Process.ManagedProcess.Internal.Types.Dispatcher
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance Control.Distributed.Process.ManagedProcess.Internal.Types.MessageMatcher Control.Distributed.Process.ManagedProcess.Internal.Types.ExternDispatcher
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance Control.Distributed.Process.Serializable.Serializable a => Data.Binary.Class.Binary (Control.Distributed.Process.ManagedProcess.Internal.Types.CallResponse a)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance Control.Distributed.Process.Serializable.Serializable m => Data.Binary.Class.Binary (Control.Distributed.Process.ManagedProcess.Internal.Types.ControlPort m)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance Control.Monad.Catch.MonadCatch (Control.Distributed.Process.ManagedProcess.Internal.Types.GenProcess s)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance Control.Monad.Catch.MonadMask (Control.Distributed.Process.ManagedProcess.Internal.Types.GenProcess s)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance Control.Monad.Catch.MonadThrow (Control.Distributed.Process.ManagedProcess.Internal.Types.GenProcess s)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance Control.Monad.Fix.MonadFix (Control.Distributed.Process.ManagedProcess.Internal.Types.GenProcess s)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance Control.Monad.IO.Class.MonadIO (Control.Distributed.Process.ManagedProcess.Internal.Types.GenProcess s)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance Control.Monad.State.Class.MonadState (Control.Distributed.Process.ManagedProcess.Internal.Types.State s) (Control.Distributed.Process.ManagedProcess.Internal.Types.GenProcess s)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance Data.Binary.Class.Binary (Control.Distributed.Process.ManagedProcess.Internal.Types.CallRef a)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance Data.Binary.Class.Binary Control.Distributed.Process.ManagedProcess.Internal.Types.CallRejected
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance GHC.Base.Applicative (Control.Distributed.Process.ManagedProcess.Internal.Types.GenProcess s)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance GHC.Base.Functor (Control.Distributed.Process.ManagedProcess.Internal.Types.GenProcess s)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance GHC.Base.Monad (Control.Distributed.Process.ManagedProcess.Internal.Types.GenProcess s)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance GHC.Classes.Eq (Control.Distributed.Process.ManagedProcess.Internal.Types.CallRef a)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance GHC.Classes.Eq (Control.Distributed.Process.ManagedProcess.Internal.Types.ControlPort m)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance GHC.Classes.Eq Control.Distributed.Process.ManagedProcess.Internal.Types.CallRejected
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance GHC.Classes.Eq Control.Distributed.Process.ManagedProcess.Internal.Types.UnhandledMessagePolicy
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance GHC.Classes.Eq a => GHC.Classes.Eq (Control.Distributed.Process.ManagedProcess.Internal.Types.CallResponse a)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance GHC.Generics.Generic (Control.Distributed.Process.ManagedProcess.Internal.Types.CallRef a)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance GHC.Generics.Generic (Control.Distributed.Process.ManagedProcess.Internal.Types.CallResponse a)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance GHC.Generics.Generic (Control.Distributed.Process.ManagedProcess.Internal.Types.Message a b)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance GHC.Generics.Generic Control.Distributed.Process.ManagedProcess.Internal.Types.CallRejected
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance GHC.Show.Show (Control.Distributed.Process.ManagedProcess.Internal.Types.CallRef a)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance GHC.Show.Show (Control.Distributed.Process.ManagedProcess.Internal.Types.ControlPort m)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance GHC.Show.Show Control.Distributed.Process.ManagedProcess.Internal.Types.CallRejected
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance GHC.Show.Show Control.Distributed.Process.ManagedProcess.Internal.Types.UnhandledMessagePolicy
+ Control.Distributed.Process.ManagedProcess.Internal.Types: instance GHC.Show.Show a => GHC.Show.Show (Control.Distributed.Process.ManagedProcess.Internal.Types.CallResponse a)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: isCleanShutdown :: ExitState s -> Bool
+ Control.Distributed.Process.ManagedProcess.Internal.Types: lift :: Process a -> GenProcess s a
+ Control.Distributed.Process.ManagedProcess.Internal.Types: liftIO :: IO a -> GenProcess s a
+ Control.Distributed.Process.ManagedProcess.Internal.Types: makeRef :: Recipient -> CallId -> CallRef a
+ Control.Distributed.Process.ManagedProcess.Internal.Types: matchDispatch :: MessageMatcher d => UnhandledMessagePolicy -> s -> d s -> Match (ProcessAction s)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: matchExtern :: ExternMatcher d => UnhandledMessagePolicy -> s -> d s -> Match Message
+ Control.Distributed.Process.ManagedProcess.Internal.Types: matchMapExtern :: forall m s. ExternMatcher d => UnhandledMessagePolicy -> s -> (Message -> m) -> d s -> Match m
+ Control.Distributed.Process.ManagedProcess.Internal.Types: newControlChan :: (Serializable m) => Process (ControlChannel m)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: newtype CallRef a
+ Control.Distributed.Process.ManagedProcess.Internal.Types: newtype ControlChannel m
+ Control.Distributed.Process.ManagedProcess.Internal.Types: newtype ControlPort m
+ Control.Distributed.Process.ManagedProcess.Internal.Types: newtype Priority a
+ Control.Distributed.Process.ManagedProcess.Internal.Types: recipient :: CallRef a -> Recipient
+ Control.Distributed.Process.ManagedProcess.Internal.Types: rejectToCaller :: forall a b. Message a b -> String -> Process ()
+ Control.Distributed.Process.ManagedProcess.Internal.Types: runProcess :: State s -> GenProcess s a -> Process (a, State s)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: tag :: CallRef a -> CallId
+ Control.Distributed.Process.ManagedProcess.Internal.Types: type Action s = Process (ProcessAction s)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: type ActionHandler s a = s -> a -> Action s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: type CallHandler s a b = s -> a -> Reply b s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: type CallId = MonitorRef
+ Control.Distributed.Process.ManagedProcess.Internal.Types: type CastHandler s a = ActionHandler s a
+ Control.Distributed.Process.ManagedProcess.Internal.Types: type ChannelHandler s a b = SendPort b -> ActionHandler s a
+ Control.Distributed.Process.ManagedProcess.Internal.Types: type DeferredCallHandler s a b = CallRef b -> CallHandler s a b
+ Control.Distributed.Process.ManagedProcess.Internal.Types: type InfoHandler s a = ActionHandler s a
+ Control.Distributed.Process.ManagedProcess.Internal.Types: type InitHandler a s = a -> Process (InitResult s)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: type Limit = Maybe Int
+ Control.Distributed.Process.ManagedProcess.Internal.Types: type Queue = PriorityQ Int Message
+ Control.Distributed.Process.ManagedProcess.Internal.Types: type Reply b s = Process (ProcessReply b s)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: type ShutdownHandler s = ExitState s -> ExitReason -> Process ()
+ Control.Distributed.Process.ManagedProcess.Internal.Types: type State s = IORef (ProcessState s)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: type StatelessCallHandler s a b = CallRef b -> a -> Reply b s
+ Control.Distributed.Process.ManagedProcess.Internal.Types: type StatelessChannelHandler s a b = SendPort b -> StatelessHandler s a
+ Control.Distributed.Process.ManagedProcess.Internal.Types: type StatelessHandler s a = a -> (s -> Action s)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: type TimeoutHandler s = ActionHandler s Delay
+ Control.Distributed.Process.ManagedProcess.Internal.Types: unsafeInitCall :: forall s a b. (Addressable s, NFSerializable a, NFSerializable b) => s -> a -> Process (CallRef b)
+ Control.Distributed.Process.ManagedProcess.Internal.Types: waitResponse :: forall b. (Serializable b) => Maybe TimeInterval -> CallRef b -> Process (Maybe (Either ExitReason b))
+ Control.Distributed.Process.ManagedProcess.Server: become :: forall s. ProcessDefinition s -> s -> Action s
+ Control.Distributed.Process.ManagedProcess.Server.Priority: act :: forall s. GenProcess s () -> Action s
+ Control.Distributed.Process.ManagedProcess.Server.Priority: apiSafe :: forall s m b. (Serializable m, Serializable b) => (s -> m -> Maybe b -> Bool) -> DispatchFilter s
+ Control.Distributed.Process.ManagedProcess.Server.Priority: runAfter :: forall s m. (Serializable m) => TimeInterval -> m -> GenProcess s ()
+ Control.Distributed.Process.ManagedProcess.Server.Priority: safe :: forall s m. (Serializable m) => (s -> m -> Bool) -> DispatchFilter s
+ Control.Distributed.Process.ManagedProcess.Server.Priority: safely :: forall s. (s -> Message -> Bool) -> DispatchFilter s
Files
- distributed-process-client-server.cabal +2/−3
- src/Control/Distributed/Process/ManagedProcess/Internal/GenProcess.hs +27/−6
- src/Control/Distributed/Process/ManagedProcess/Internal/Types.hs +2/−0
- src/Control/Distributed/Process/ManagedProcess/Server.hs +4/−0
- src/Control/Distributed/Process/ManagedProcess/Server/Priority.hs +43/−0
- tests/TestPrioritisedProcess.hs +112/−0
distributed-process-client-server.cabal view
@@ -1,5 +1,5 @@ name: distributed-process-client-server-version: 0.2.0+version: 0.2.1 cabal-version: >=1.8 build-type: Simple license: BSD3@@ -56,8 +56,7 @@ Control.Distributed.Process.ManagedProcess.Server, Control.Distributed.Process.ManagedProcess.Server.Priority, Control.Distributed.Process.ManagedProcess.Server.Restricted,- Control.Distributed.Process.ManagedProcess.Timer- other-modules:+ Control.Distributed.Process.ManagedProcess.Timer, Control.Distributed.Process.ManagedProcess.Internal.Types, Control.Distributed.Process.ManagedProcess.Internal.GenProcess
src/Control/Distributed/Process/ManagedProcess/Internal/GenProcess.hs view
@@ -29,6 +29,7 @@ , GenProcess , peek , push+ , enqueue , addUserTimer , removeUserTimer , act@@ -118,6 +119,8 @@ -- Priority Mailbox Handling -- -------------------------------------------------------------------------------- +type Safe = Bool+ -- | Evaluate the given function over the @ProcessState s@ for the caller, and -- return the result. gets :: forall s a . (ProcessState s -> a) -> GenProcess s a@@ -277,6 +280,12 @@ prioritise = (\_ m' -> return $ Just ((101 :: Int), m')) :: s -> Message -> Process (Maybe (Int, Message)) } ] m +-- | Enqueue a message to the back of the internal priority queue.+enqueue :: forall s . Message -> GenProcess s ()+enqueue m = do+ st <- processState+ enqueueMessage st [] m+ -- | Enqueue a message in the internal priority queue. The given message will be -- evaluated by all the supplied prioritisers, and if none match it, then it will -- be assigned the lowest possible priority (i.e. put at the back of the queue).@@ -416,6 +425,10 @@ | ProcessStop xr <- ac = return xr | ProcessStopping ps' xr <- ac = setProcessState ps' >> return xr | ProcessHibernate d' s' <- ac = (lift $ block d') >> recvQueueAux s'+ | ProcessBecome pd' ps' <- ac = do+ modifyState $ \st@ProcessState{..} -> st { procDef = pd', procState = ps' }+ -- liftIO $ putStrLn "modified process def"+ recvQueue | otherwise {- compiler foo -} = return $ ExitOther "IllegalState" recvQueueAux st = setProcessState st >> recvQueue@@ -459,19 +472,26 @@ (up, pf) <- gets $ liftA2 (,) (unhandledMessagePolicy . procDef) procFilters case pf of [] -> consumeMessage- _ -> filterMessage (filterNext up pf Nothing)+ _ -> filterMessage (filterNext False up pf Nothing) consumeMessage = applyNext dequeue processApply filterMessage = applyNext peek - filterNext :: UnhandledMessagePolicy+ filterNext :: Safe+ -> UnhandledMessagePolicy -> [DispatchFilter s] -> Maybe (Filter s) -> Message -> GenProcess s (ProcessAction s)- filterNext mp' fs mf msg+ filterNext isSafe mp' fs mf msg+ | Just (FilterSafe s') <- mf = filterNext True mp' fs (Just $ FilterOk s') msg | Just (FilterSkip s') <- mf = setProcessState s' >> dequeue >> return ProcessSkip | Just (FilterStop s' r) <- mf = return $ ProcessStopping s' r+ | isSafe+ , Just (FilterOk s') <- mf+ , [] <- fs = do setProcessState s'+ act' <- processApply msg+ dequeue >> return act' | Just (FilterOk s') <- mf , [] <- fs = setProcessState s' >> applyNext dequeue processApply | Nothing <- mf, [] <- fs = applyNext dequeue processApply@@ -479,12 +499,12 @@ , (f:fs') <- fs = do setProcessState s' act' <- lift $ dynHandleFilter s' f msg- filterNext mp' fs' act' msg+ filterNext isSafe mp' fs' act' msg | Just (FilterReject _ s') <- mf = do setProcessState s' >> dequeue >>= lift . applyPolicy mp' s' . fromJust | Nothing <- mf {- filter didn't apply to the input type -} , (f:fs') <- fs = processState >>= \s' -> do- lift (dynHandleFilter s' f msg) >>= \a -> filterNext mp' fs' a msg+ lift (dynHandleFilter s' f msg) >>= \a -> filterNext isSafe mp' fs' a msg applyNext :: (GenProcess s (Maybe Message)) -> (Message -> GenProcess s (ProcessAction s))@@ -497,13 +517,13 @@ processApply msg = do (def, pState) <- gets $ liftA2 (,) procDef procState- let pol = unhandledMessagePolicy def apiMatchers = map (dynHandleMessage pol pState) (apiHandlers def) infoMatchers = map (dynHandleMessage pol pState) (infoHandlers def) extMatchers = map (dynHandleMessage pol pState) (externHandlers def) shutdown' = dynHandleMessage pol pState shutdownHandler' ms' = (shutdown':extMatchers) ++ apiMatchers ++ infoMatchers+ -- liftIO $ putStrLn $ "we have " ++ (show $ (length apiMatchers, length infoMatchers)) ++ " handlers" processApplyAux ms' pol pState msg processApplyAux [] p' s' m' = lift $ applyPolicy p' s' m'@@ -709,6 +729,7 @@ (ProcessHibernate d' s') -> block d' >> recvLoop pDef s' recvDelay (ProcessStop r) -> handleStop (LastKnown pState) r >> return (r :: ExitReason) (ProcessStopping s' r) -> handleStop (LastKnown s') r >> return (r :: ExitReason)+ (ProcessBecome d' s') -> recvLoop d' s' recvDelay (ProcessActivity _) -> die $ "recvLoop.InvalidState - ProcessActivityNotSupported" where matchAux :: UnhandledMessagePolicy
src/Control/Distributed/Process/ManagedProcess/Internal/Types.hs view
@@ -318,6 +318,7 @@ | ProcessHibernate TimeInterval s -- ^ hibernate for /delay/ | ProcessStop ExitReason -- ^ stop the process, giving @ExitReason@ | ProcessStopping s ExitReason -- ^ stop the process with @ExitReason@, with updated state+ | ProcessBecome (ProcessDefinition s) s -- ^ changes the current process definition -- | Returned from handlers for the synchronous 'call' protocol, encapsulates -- the reply data /and/ the action to take after sending the reply. A handler@@ -447,6 +448,7 @@ -- for internal use. For an API for working with filters, -- see "Control.Distributed.Process.ManagedProcess.Priority". data Filter s = FilterOk s+ | FilterSafe s | forall m . (Show m) => FilterReject m s | FilterSkip s | FilterStop s ExitReason
src/Control/Distributed/Process/ManagedProcess/Server.hs view
@@ -32,6 +32,7 @@ , replyChan , reject , rejectWith+ , become -- * Stateless actions , noReply_ , haltNoReply_@@ -188,6 +189,9 @@ -- hibernate_ :: StatelessHandler s TimeInterval hibernate_ d = return . ProcessHibernate d++become :: forall s . ProcessDefinition s -> s -> Action s+become def st = return $ ProcessBecome def st -- | Instructs the process to terminate, giving the supplied reason. If a valid -- 'shutdownHandler' is installed, it will be called with the 'ExitReason'
src/Control/Distributed/Process/ManagedProcess/Server/Priority.hs view
@@ -4,6 +4,7 @@ {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE EmptyDataDecls #-} {-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE AllowAmbiguousTypes #-} ----------------------------------------------------------------------------- -- |@@ -44,6 +45,9 @@ , ensureM , Filter() , DispatchFilter()+ , safe+ , apiSafe+ , safely , Message() , evalAfter , currentTimeout@@ -57,6 +61,8 @@ , peek , push , addUserTimer+ , act+ , runAfter ) where import Control.Distributed.Process hiding (call, Message)@@ -77,6 +83,8 @@ , peek , push , evalAfter+ , act+ , runAfter ) import Control.Distributed.Process.ManagedProcess.Internal.Types import Control.Distributed.Process.Serializable@@ -106,6 +114,10 @@ , rawHandler :: s -> P.Message -> Process (Maybe (Filter s)) } -- ^ A raw handler, usable where the target handler is based on @handleRaw@ | HandleState { stateHandler :: s -> Process (Maybe (Filter s)) }+ | HandleSafe+ {+ safeCheck :: s -> P.Message -> Process Bool+ } -- ^ A safe wrapper {- check :: forall c s m . (Check c s m)@@ -125,6 +137,10 @@ c <- apiCheck s m' if c then return $ FilterOk s else apiHandler s m+ | HandleSafe{..} <- h = FilterRaw $ \s m -> do+ c <- safeCheck s m+ let ctr = if c then FilterSafe else FilterOk+ return $ Just $ ctr s where procUnless s _ _ True = return $ FilterOk s@@ -171,6 +187,33 @@ -> (s -> m -> Process (Filter s)) -> FilterHandler s info_ c h = info (const $ c) h++apiSafe :: forall s m b . (Serializable m, Serializable b)+ => (s -> m -> Maybe b -> Bool)+ -> DispatchFilter s+apiSafe c = check $ HandleSafe (go c)+ where+ go c' s (i :: P.Message) = do+ m <- unwrapMessage i :: Process (Maybe (Message m b))+ case m of+ Just (CallMessage m' _) -> return $ c' s m' Nothing+ Just (CastMessage m') -> return $ c' s m' Nothing+ Just (ChanMessage m' _) -> return $ c' s m' Nothing+ Nothing -> return False++safe :: forall s m . (Serializable m)+ => (s -> m -> Bool)+ -> DispatchFilter s+safe c = check $ HandleSafe (go c)+ where+ go c' s (i :: P.Message) = do+ m <- unwrapMessage i :: Process (Maybe m)+ case m of+ Just m' -> return $ c' s m'+ Nothing -> return False++safely :: forall s . (s -> P.Message -> Bool) -> DispatchFilter s+safely c = check $ HandleSafe $ \s m -> return (c s m) -- | Create a filter expression that will reject all messages of a specific type. reject :: forall s m r . (Show r)
tests/TestPrioritisedProcess.hs view
@@ -29,6 +29,7 @@ import Data.Binary import Data.Either (rights) import Data.List (isInfixOf)+import Data.Maybe (isNothing) import Data.Typeable (Typeable) #if ! MIN_VERSION_base(4,6,0)@@ -270,6 +271,111 @@ stash result $ m == 25 kill pid "done" +testServerSwap :: TestResult Bool -> Process ()+testServerSwap result = do+ us <- getSelfPid+ let def2 = statelessProcess { apiHandlers = [ handleCast (\s (i :: Int) -> send us (i, i+1) >> continue s)+ , handleCall_ (\(i :: Int) -> return (i * 5))+ ]+ , unhandledMessagePolicy = Drop -- otherwise `call` would fail+ }+ let def = statelessProcess+ { apiHandlers = [ handleCall_ (\(m :: String) -> return m) ]+ , infoHandlers = [ handleInfo (\s () -> become def2 s) ]+ } `prioritised` []++ pid <- spawnLocal $ pserve () (statelessInit Infinity) def++ m1 <- call pid "hello there"+ let a1 = m1 == "hello there"++ send pid () --changeover++ m2 <- callTimeout pid "are you there?" (seconds 5) :: Process (Maybe String)+ let a2 = isNothing m2++ cast pid (45 :: Int)+ res <- receiveWait [ matchIf (\(i :: Int) -> i == 45) (return . Left)+ , match (\(_ :: Int, j :: Int) -> return $ Right j) ]++ let a3 = res == (Right 46)++ m4 <- call pid (20 :: Int) :: Process Int+ let a4 = m4 == 100++ stash result $ a1 && a2 && a3 && a4++testSafeExecutionContext :: TestResult Bool -> Process ()+testSafeExecutionContext result = do+ let t = (asTimeout $ seconds 5)+ (sigSp, rp) <- newChan+ (wp, lp) <- newChan+ let def = statelessProcess+ { apiHandlers = [ handleCall_ (\(m :: String) -> stranded rp wp Nothing >> return m) ]+ , infoHandlers = [ handleInfo (\s (m :: String) -> stranded rp wp (Just m) >> continue s) ]+ , exitHandlers = [ handleExit (\_ s (_ :: String) -> continue s) ]+ } `prioritised` []++ let spec = def { filters = [+ safe (\_ (_ :: String) -> True)+ , apiSafe (\_ (_ :: String) (_ :: Maybe String) -> True)+ ]+ }++ pid <- spawnLocal $ pserve () (statelessInit Infinity) spec+ send pid "hello" -- pid can't process this as it's stuck waiting on rp++ sleep $ seconds 3+ exit pid "ooops" -- now we force an exit signal once the receiveWait finishes+ sendChan sigSp () -- and allow the receiveWait to complete+ send pid "hi again"++ -- at this point, "hello" should still be in the backing queue/mailbox+ sleep $ seconds 3++ -- We should still be seeing "hello", since the 'safe' block saved us from+ -- losing a message when we handled and swallowed the exit signal.+ -- We should not see "hi again" until after "hello" has been processed+ h <- receiveChanTimeout t lp+ -- say $ "first response: " ++ (show h)+ let a1 = h == (Just "hello")++ sleep $ seconds 3++ -- now we should have "hi again" waiting in the mailbox...+ sendChan sigSp () -- we must release the handler a second time...+ h2 <- receiveChanTimeout t lp+ -- say $ "second response: " ++ (show h2)+ let a2 = h2 == (Just "hi again")++ void $ spawnLocal $ call pid "reply-please" >>= sendChan wp++ -- the call handler should be stuck waiting on rp+ Nothing <- receiveChanTimeout (asTimeout $ seconds 2) lp++ -- now let's force an exit, then release the handler to see if it runs again...+ exit pid "ooops2"++ sleep $ seconds 2+ sendChan sigSp ()++ h3 <- receiveChanTimeout t lp+-- say $ "third response: " ++ (show h3)+ let a3 = h3 == (Just "reply-please")++ stash result $ a1 && a2 && a3++ where++ stranded :: ReceivePort () -> SendPort String -> Maybe String -> Process ()+ stranded gate chan str = do+ -- say $ "stranded with " ++ (show str)+ void $ receiveWait [ matchChan gate return ]+ sleep $ seconds 1+ case str of+ Nothing -> return ()+ Just s -> sendChan chan s+ testExternalTimedOverflowHandling :: TestResult Bool -> Process () testExternalTimedOverflowHandling result = do (pid, cp) <- launchStmOverloadServer -- default 10k mailbox drain limit@@ -475,6 +581,12 @@ , testCase "Firing internal timeouts" (delayedAssertion "expected our info handler to run after the timeout" localNode True testUserTimerHandling)+ , testCase "Creating 'Safe' Handlers"+ (delayedAssertion "expected our handler to run on the old message"+ localNode True testSafeExecutionContext)+ , testCase "Swapping ProcessDefinitions at runtime"+ (delayedAssertion "expected our handler to exist in the new handler list"+ localNode True testServerSwap) ] ]