| Safe Haskell | None |
|---|---|
| Language | Haskell2010 |
Control.Eff.Concurrent.Process
Contents
- Process Effect
- Effect Type Handling
- ProcessId Type
- Scheduler Effect Identification
- Process State
- Yielding
- Sending Messages
- Utilities
- Receiving Messages
- Selecting Messages to Receive
- Process Life Cycle Management
- Spawning
- Process Exit or Interrupt
- Links
- Monitors
- Process Interrupt Handling
- Process Operation Execution
- Exit Or Interrupt Reasons
Description
The message passing effect.
This module describes an abstract message passing effect, and a process effect, mimicking Erlang's process and message semantics.
Two scheduler implementations for the Process effect are provided:
- A scheduler using
forkIO, i.e. relying on the multi threaded GHC runtime: Control.Eff.Concurrent.Process.ForkIOScheduler - And a pure(rer) coroutine based scheduler in: Control.Eff.Concurrent.Process.SingleThreadedScheduler
Synopsis
- data Process (r :: [Type -> Type]) b where
- FlushMessages :: Process r (ResumeProcess [Dynamic])
- YieldProcess :: Process r (ResumeProcess ())
- SelfPid :: Process r (ResumeProcess ProcessId)
- Spawn :: Eff (Process r ': r) () -> Process r (ResumeProcess ProcessId)
- SpawnLink :: Eff (Process r ': r) () -> Process r (ResumeProcess ProcessId)
- GetProcessState :: ProcessId -> Process r (ResumeProcess (Maybe ProcessState))
- Shutdown :: ExitReason NoRecovery -> Process r a
- SendShutdown :: ProcessId -> ExitReason NoRecovery -> Process r (ResumeProcess ())
- SendInterrupt :: ProcessId -> InterruptReason -> Process r (ResumeProcess ())
- SendMessage :: ProcessId -> Dynamic -> Process r (ResumeProcess ())
- ReceiveSelectedMessage :: forall r a. MessageSelector a -> Process r (ResumeProcess a)
- MakeReference :: Process r (ResumeProcess Int)
- Monitor :: ProcessId -> Process r (ResumeProcess MonitorReference)
- Demonitor :: MonitorReference -> Process r (ResumeProcess ())
- Link :: ProcessId -> Process r (ResumeProcess ())
- Unlink :: ProcessId -> Process r (ResumeProcess ())
- newtype ProcessId = ProcessId {}
- fromProcessId :: Iso' ProcessId Int
- type ConsProcess r = Process r ': r
- data ResumeProcess v where
- Interrupted :: InterruptReason -> ResumeProcess v
- ResumeWith :: a -> ResumeProcess a
- data SchedulerProxy :: [Type -> Type] -> Type where
- SchedulerProxy :: SchedulerProxy q
- SP :: SchedulerProxy q
- Scheduler :: SchedulerProxy q
- type HasScheduler q = ?_schedulerProxy :: SchedulerProxy q
- getSchedulerProxy :: HasScheduler q => SchedulerProxy q
- withSchedulerProxy :: SchedulerProxy q -> (HasScheduler q => a) -> a
- thisSchedulerProxy :: Eff (Process r ': r) (SchedulerProxy r)
- data ProcessState
- yieldProcess :: forall r q. (SetMember Process (Process q) r, HasCallStack, Member Interrupts r) => SchedulerProxy q -> Eff r ()
- sendMessage :: forall r q o. (SetMember Process (Process q) r, HasCallStack, Member Interrupts r, Typeable o) => SchedulerProxy q -> ProcessId -> o -> Eff r ()
- sendAnyMessage :: forall r q. (SetMember Process (Process q) r, HasCallStack, Member Interrupts r) => SchedulerProxy q -> ProcessId -> Dynamic -> Eff r ()
- sendShutdown :: forall r q. (SetMember Process (Process q) r, HasCallStack, Member Interrupts r) => SchedulerProxy q -> ProcessId -> ExitReason NoRecovery -> Eff r ()
- sendInterrupt :: forall r q. (SetMember Process (Process q) r, HasCallStack, Member Interrupts r) => SchedulerProxy q -> ProcessId -> InterruptReason -> Eff r ()
- makeReference :: (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => SchedulerProxy q -> Eff r Int
- receiveMessage :: forall a r q. (HasCallStack, Typeable a, Show a, SetMember Process (Process q) r, Member Interrupts r) => SchedulerProxy q -> Eff r a
- receiveSelectedMessage :: forall r q a. (HasCallStack, Show a, SetMember Process (Process q) r, Member Interrupts r) => SchedulerProxy q -> MessageSelector a -> Eff r a
- flushMessages :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r, HasScheduler q) => Eff r [Dynamic]
- receiveAnyMessage :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => SchedulerProxy q -> Eff r Dynamic
- receiveLoop :: forall r q a endOfLoopResult. (SetMember Process (Process q) r, HasCallStack, Typeable a) => SchedulerProxy q -> (Either InterruptReason a -> Eff r (Maybe endOfLoopResult)) -> Eff r endOfLoopResult
- receiveSelectedLoop :: forall r q a endOfLoopResult. (SetMember Process (Process q) r, HasCallStack) => SchedulerProxy q -> MessageSelector a -> (Either InterruptReason a -> Eff r (Maybe endOfLoopResult)) -> Eff r endOfLoopResult
- receiveAnyLoop :: forall r q endOfLoopResult. (SetMember Process (Process q) r, HasCallStack) => SchedulerProxy q -> (Either InterruptReason Dynamic -> Eff r (Maybe endOfLoopResult)) -> Eff r endOfLoopResult
- data MessageSelector a
- selectMessage :: (NFData t, Typeable t) => MessageSelector t
- selectMessageLazy :: Typeable t => MessageSelector t
- selectMessageProxy :: forall proxy t. (NFData t, Typeable t) => proxy t -> MessageSelector t
- selectMessageProxyLazy :: forall proxy t. Typeable t => proxy t -> MessageSelector t
- filterMessage :: (Typeable a, NFData a) => (a -> Bool) -> MessageSelector a
- filterMessageLazy :: Typeable a => (a -> Bool) -> MessageSelector a
- selectMessageWith :: (Typeable a, NFData b) => (a -> Maybe b) -> MessageSelector b
- selectMessageWithLazy :: Typeable a => (a -> Maybe b) -> MessageSelector b
- selectDynamicMessage :: NFData a => (Dynamic -> Maybe a) -> MessageSelector a
- selectDynamicMessageLazy :: (Dynamic -> Maybe a) -> MessageSelector a
- selectAnyMessageLazy :: MessageSelector Dynamic
- self :: (HasCallStack, SetMember Process (Process q) r) => SchedulerProxy q -> Eff r ProcessId
- isProcessAlive :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => SchedulerProxy q -> ProcessId -> Eff r Bool
- spawn :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => Eff (InterruptableProcess q) () -> Eff r ProcessId
- spawn_ :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => Eff (InterruptableProcess q) () -> Eff r ()
- spawnLink :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => Eff (InterruptableProcess q) () -> Eff r ProcessId
- spawnRaw :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => Eff (ConsProcess q) () -> Eff r ProcessId
- spawnRaw_ :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => Eff (ConsProcess q) () -> Eff r ()
- exitBecause :: forall r q a. (HasCallStack, SetMember Process (Process q) r) => SchedulerProxy q -> ExitReason NoRecovery -> Eff r a
- exitNormally :: forall r q a. (HasCallStack, SetMember Process (Process q) r) => SchedulerProxy q -> Eff r a
- exitWithError :: forall r q a. (HasCallStack, SetMember Process (Process q) r) => SchedulerProxy q -> String -> Eff r a
- linkProcess :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => SchedulerProxy q -> ProcessId -> Eff r ()
- unlinkProcess :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => SchedulerProxy q -> ProcessId -> Eff r ()
- monitor :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => SchedulerProxy q -> ProcessId -> Eff r MonitorReference
- demonitor :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => SchedulerProxy q -> MonitorReference -> Eff r ()
- data ProcessDown = ProcessDown {}
- selectProcessDown :: MonitorReference -> MessageSelector ProcessDown
- becauseProcessIsDown :: ProcessDown -> InterruptReason
- data MonitorReference = MonitorReference {}
- withMonitor :: (HasCallStack, Member Interrupts r, SetMember Process (Process q) r, Member Interrupts r) => SchedulerProxy q -> ProcessId -> (MonitorReference -> Eff r a) -> Eff r a
- receiveWithMonitor :: (HasCallStack, Member Interrupts r, SetMember Process (Process q) r, Member Interrupts r, Typeable a, Show a) => SchedulerProxy q -> ProcessId -> MessageSelector a -> Eff r (Either ProcessDown a)
- provideInterruptsShutdown :: forall e a. Eff (InterruptableProcess e) a -> Eff (ConsProcess e) a
- handleInterrupts :: (HasCallStack, Member Interrupts r) => (InterruptReason -> Eff r a) -> Eff r a -> Eff r a
- exitOnInterrupt :: (HasCallStack, Member Interrupts r, SetMember Process (Process q) r) => SchedulerProxy q -> Eff r a -> Eff r a
- logInterrupts :: (HasCallStack, '[Interrupts, Logs LogMessage] <:: r) => Eff r () -> Eff r ()
- provideInterrupts :: HasCallStack => Eff (Interrupts ': r) a -> Eff r (Either InterruptReason a)
- mergeEitherInterruptAndExitReason :: Either InterruptReason (ExitReason NoRecovery) -> ExitReason NoRecovery
- interrupt :: (HasCallStack, Member Interrupts r) => InterruptReason -> Eff r a
- executeAndResume :: forall q r v. (SetMember Process (Process q) r, HasCallStack) => Process q (ResumeProcess v) -> Eff r (Either (ExitReason Recoverable) v)
- executeAndResumeOrExit :: forall r q v. (SetMember Process (Process q) r, HasCallStack) => Process q (ResumeProcess v) -> Eff r v
- executeAndResumeOrThrow :: forall q r v. (SetMember Process (Process q) r, HasCallStack, Member Interrupts r) => Process q (ResumeProcess v) -> Eff r v
- data ExitReason (t :: ExitRecovery) where
- ProcessNotRunning :: ProcessId -> ExitReason Recoverable
- LinkedProcessCrashed :: ProcessId -> ExitReason Recoverable
- ProcessError :: String -> ExitReason Recoverable
- ExitNormally :: ExitReason NoRecovery
- NotRecovered :: ExitReason Recoverable -> ExitReason NoRecovery
- UnexpectedException :: String -> String -> ExitReason NoRecovery
- Killed :: ExitReason NoRecovery
- data ExitRecovery
- type InterruptReason = ExitReason Recoverable
- type Interrupts = Exc InterruptReason
- type InterruptableProcess e = Interrupts ': ConsProcess e
- data ExitSeverity
- = NormalExit
- | Crash
- data SomeExitReason where
- SomeExitReason :: ExitReason x -> SomeExitReason
- toExitRecovery :: ExitReason r -> ExitRecovery
- isRecoverable :: ExitReason x -> Bool
- toExitSeverity :: ExitReason e -> ExitSeverity
- isBecauseDown :: Maybe ProcessId -> ExitReason r -> Bool
- isCrash :: ExitReason x -> Bool
- toCrashReason :: ExitReason x -> Maybe String
- fromSomeExitReason :: SomeExitReason -> Either (ExitReason NoRecovery) InterruptReason
- logProcessExit :: (HasCallStack, Member (Logs LogMessage) e) => ExitReason x -> Eff e ()
Process Effect
Effect Type Handling
data Process (r :: [Type -> Type]) b where Source #
The process effect is the basis for message passing concurrency. This effect describes an interface for concurrent, communicating isolated processes identified uniquely by a process-id.
Processes can raise exceptions that can be caught, exit gracefully or with an error, or be killed by other processes, with the option of ignoring the shutdown request.
Process Scheduling is implemented in different modules. All scheduler implementations should follow some basic rules:
- fair scheduling
- sending a message does not block
- receiving a message does block
- spawning a child blocks only a very moment
- a newly spawned process shall be scheduled before the parent process after
- the spawnRaw
- when the first process exists, all process should be killed immediately
Constructors
| FlushMessages :: Process r (ResumeProcess [Dynamic]) | Remove all messages from the process' message queue |
| YieldProcess :: Process r (ResumeProcess ()) | In cooperative schedulers, this will give processing time to the scheduler. Every other operation implicitly serves the same purpose. Since: 0.12.0 |
| SelfPid :: Process r (ResumeProcess ProcessId) | Return the current |
| Spawn :: Eff (Process r ': r) () -> Process r (ResumeProcess ProcessId) | Start a new process, the new process will execute an effect, the function
will return immediately with a |
| SpawnLink :: Eff (Process r ': r) () -> Process r (ResumeProcess ProcessId) | Start a new process, and Since: 0.12.0 |
| GetProcessState :: ProcessId -> Process r (ResumeProcess (Maybe ProcessState)) | Get the process state (or |
| Shutdown :: ExitReason NoRecovery -> Process r a | Shutdown the process; irregardles of the exit reason, this function never returns, |
| SendShutdown :: ProcessId -> ExitReason NoRecovery -> Process r (ResumeProcess ()) | Raise an error, that can be handled. |
| SendInterrupt :: ProcessId -> InterruptReason -> Process r (ResumeProcess ()) | Request that another a process interrupts. The targeted process is interrupted
and gets an |
| SendMessage :: ProcessId -> Dynamic -> Process r (ResumeProcess ()) | Send a message to a process addressed by the |
| ReceiveSelectedMessage :: forall r a. MessageSelector a -> Process r (ResumeProcess a) | Receive a message that matches a criterium.
This should block until an a message was received. The message is returned
as a |
| MakeReference :: Process r (ResumeProcess Int) | Generate a unique |
| Monitor :: ProcessId -> Process r (ResumeProcess MonitorReference) | Monitor another process. When the monitored process exits a
Since: 0.12.0 |
| Demonitor :: MonitorReference -> Process r (ResumeProcess ()) | Remove a monitor. Since: 0.12.0 |
| Link :: ProcessId -> Process r (ResumeProcess ()) | Connect the calling process to another process, such that
if one of the processes crashes (i.e. Since: 0.12.0 |
| Unlink :: ProcessId -> Process r (ResumeProcess ()) | Unlink the calling proccess from the other process. Since: 0.12.0 |
ProcessId Type
Each process is identified by a single process id, that stays constant throughout the life cycle of a process. Also, message sending relies on these values to address messages to processes.
Constructors
| ProcessId | |
Fields | |
Instances
type ConsProcess r = Process r ': r Source #
Cons Process onto a list of effects.
data ResumeProcess v where Source #
Every Process action returns it's actual result wrapped in this type. It
will allow to signal errors as well as pass on normal results such as
incoming messages.
Constructors
| Interrupted :: InterruptReason -> ResumeProcess v | The current operation of the process was interrupted with a
|
| ResumeWith :: a -> ResumeProcess a | The process may resume to do work, using the given result. |
Instances
Scheduler Effect Identification
data SchedulerProxy :: [Type -> Type] -> Type where Source #
Every function for Process things needs such a proxy value
for the low-level effect list, i.e. the effects identified by
r in , this might be dependent on the
scheduler implementation.Process r : r
Constructors
| SchedulerProxy :: SchedulerProxy q | Tell the typechecker what effects we have below |
| SP :: SchedulerProxy q | Like |
| Scheduler :: SchedulerProxy q | Like |
type HasScheduler q = ?_schedulerProxy :: SchedulerProxy q Source #
A constraint for the implicit SchedulerProxy parameter.
Use getSchedulerProxy to query it. _EXPERIMENTAL_
Since: 0.12.0
getSchedulerProxy :: HasScheduler q => SchedulerProxy q Source #
Get access to the SchedulerProxy for the current scheduler effects.
_EXPERIMENTAL_
Since: 0.12.0
withSchedulerProxy :: SchedulerProxy q -> (HasScheduler q => a) -> a Source #
Set the SchedulerProxy to use, this satisfies HasScheduler .
_EXPERIMENTAL_
Since: 0.12.0
thisSchedulerProxy :: Eff (Process r ': r) (SchedulerProxy r) Source #
Return a SchedulerProxy for a Process effect.
Process State
data ProcessState Source #
The state that a Process is currently in.
Constructors
| ProcessBooting | The process has just been started but not
called |
| ProcessIdle | The process yielded it's timeslice |
| ProcessBusy | The process is busy with non-blocking |
| ProcessBusySending | The process is busy with sending a message |
| ProcessBusySendingShutdown | The process is busy with killing |
| ProcessBusySendingInterrupt | The process is busy with killing |
| ProcessBusyReceiving | The process blocked by a |
| ProcessBusyLinking | The process blocked by a |
| ProcessBusyUnlinking | The process blocked by a |
| ProcessBusyMonitoring | The process blocked by a |
| ProcessBusyDemonitoring | The process blocked by a |
| ProcessInterrupted | The process was interrupted |
| ProcessShuttingDown | The process was shutdown or crashed |
Instances
Yielding
yieldProcess :: forall r q. (SetMember Process (Process q) r, HasCallStack, Member Interrupts r) => SchedulerProxy q -> Eff r () Source #
Use executeAndResumeOrExit to execute YieldProcess. Refer to YieldProcess
for more information.
Sending Messages
sendMessage :: forall r q o. (SetMember Process (Process q) r, HasCallStack, Member Interrupts r, Typeable o) => SchedulerProxy q -> ProcessId -> o -> Eff r () Source #
Send a message to a process addressed by the ProcessId.
See SendMessage.
sendAnyMessage :: forall r q. (SetMember Process (Process q) r, HasCallStack, Member Interrupts r) => SchedulerProxy q -> ProcessId -> Dynamic -> Eff r () Source #
Send a Dynamic value to a process addressed by the ProcessId.
See SendMessage.
sendShutdown :: forall r q. (SetMember Process (Process q) r, HasCallStack, Member Interrupts r) => SchedulerProxy q -> ProcessId -> ExitReason NoRecovery -> Eff r () Source #
Exit a process addressed by the ProcessId. The process will exit,
it might do some cleanup, but is ultimately unrecoverable.
See SendShutdown.
sendInterrupt :: forall r q. (SetMember Process (Process q) r, HasCallStack, Member Interrupts r) => SchedulerProxy q -> ProcessId -> InterruptReason -> Eff r () Source #
Interrupts a process addressed by the ProcessId. The process might exit,
or it may continue.
| Like sendInterrupt, but also return True iff the process to exit exists.
Utilities
makeReference :: (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => SchedulerProxy q -> Eff r Int Source #
Generate a unique Int for the current process.
Receiving Messages
receiveMessage :: forall a r q. (HasCallStack, Typeable a, Show a, SetMember Process (Process q) r, Member Interrupts r) => SchedulerProxy q -> Eff r a Source #
Receive and cast the message to some Typeable instance.
See ReceiveSelectedMessage for more documentation.
This will wait for a message of the return type using receiveSelectedMessage
receiveSelectedMessage :: forall r q a. (HasCallStack, Show a, SetMember Process (Process q) r, Member Interrupts r) => SchedulerProxy q -> MessageSelector a -> Eff r a Source #
Block until a message was received, that is not Nothing after applying
a callback to it.
See ReceiveSelectedMessage for more documentation.
flushMessages :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r, HasScheduler q) => Eff r [Dynamic] Source #
Remove and return all messages currently enqueued in the process message queue.
Since: 0.12.0
receiveAnyMessage :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => SchedulerProxy q -> Eff r Dynamic Source #
Block until a message was received.
See ReceiveSelectedMessage for more documentation.
receiveLoop :: forall r q a endOfLoopResult. (SetMember Process (Process q) r, HasCallStack, Typeable a) => SchedulerProxy q -> (Either InterruptReason a -> Eff r (Maybe endOfLoopResult)) -> Eff r endOfLoopResult Source #
Like receiveSelectedLoop but refined to casting to a specific Typeable
using selectMessageLazy.
receiveSelectedLoop :: forall r q a endOfLoopResult. (SetMember Process (Process q) r, HasCallStack) => SchedulerProxy q -> MessageSelector a -> (Either InterruptReason a -> Eff r (Maybe endOfLoopResult)) -> Eff r endOfLoopResult Source #
Enter a loop to receive messages and pass them to a callback, until the
function returns Just a result.
Only the messages of the given type will be received.
If the process is interrupted by an exception of by a SendShutdown from
another process, with an exit reason that satisfies isRecoverable, then
the callback will be invoked with , otherwise the
process will be exited with the same reason using Left ProcessExitReaonexitBecause.
See also ReceiveSelectedMessage for more documentation.
receiveAnyLoop :: forall r q endOfLoopResult. (SetMember Process (Process q) r, HasCallStack) => SchedulerProxy q -> (Either InterruptReason Dynamic -> Eff r (Maybe endOfLoopResult)) -> Eff r endOfLoopResult Source #
Like receiveSelectedLoop but not selective.
See also selectAnyMessageLazy, receiveSelectedLoop.
Selecting Messages to Receive
data MessageSelector a Source #
A function that deciced if the next message will be received by
ReceiveSelectedMessage. It conveniently is an instance of
Alternative so the message selector can be combined:
>
> selectInt :: MessageSelector Int
> selectInt = selectMessage
>
> selectString :: MessageSelector String
> selectString = selectMessage
>
> selectIntOrString :: MessageSelector (Either Int String)
> selectIntOrString =
> Left $ selectTimeout| Right $ selectString
Instances
selectMessage :: (NFData t, Typeable t) => MessageSelector t Source #
Create a message selector for a value that can be obtained by fromDynamic.
It will also force the result.
Since: 0.9.1
selectMessageLazy :: Typeable t => MessageSelector t Source #
Create a message selector for a value that can be obtained by fromDynamic.
It will also force the result.
Since: 0.9.1
selectMessageProxy :: forall proxy t. (NFData t, Typeable t) => proxy t -> MessageSelector t Source #
Create a message selector for a value that can be obtained by fromDynamic
with a proxy argument. It will also force the result.
Since: 0.9.1
selectMessageProxyLazy :: forall proxy t. Typeable t => proxy t -> MessageSelector t Source #
Create a message selector for a value that can be obtained by fromDynamic
with a proxy argument. It will also force the result.
Since: 0.9.1
filterMessage :: (Typeable a, NFData a) => (a -> Bool) -> MessageSelector a Source #
Create a message selector from a predicate. It will force the result.
Since: 0.9.1
filterMessageLazy :: Typeable a => (a -> Bool) -> MessageSelector a Source #
Create a message selector from a predicate. It will force the result.
Since: 0.9.1
selectMessageWith :: (Typeable a, NFData b) => (a -> Maybe b) -> MessageSelector b Source #
Select a message of type a and apply the given function to it.
If the function returns Just The ReceiveSelectedMessage function will
return the result (sans Maybe). It will force the result.
Since: 0.9.1
selectMessageWithLazy :: Typeable a => (a -> Maybe b) -> MessageSelector b Source #
Select a message of type a and apply the given function to it.
If the function returns Just The ReceiveSelectedMessage function will
return the result (sans Maybe). It will force the result.
Since: 0.9.1
selectDynamicMessage :: NFData a => (Dynamic -> Maybe a) -> MessageSelector a Source #
Create a message selector. It will force the result.
Since: 0.9.1
selectDynamicMessageLazy :: (Dynamic -> Maybe a) -> MessageSelector a Source #
Create a message selector.
Since: 0.9.1
selectAnyMessageLazy :: MessageSelector Dynamic Source #
Create a message selector that will match every message. This is lazy
because the result is not forceed.
Since: 0.9.1
Process Life Cycle Management
self :: (HasCallStack, SetMember Process (Process q) r) => SchedulerProxy q -> Eff r ProcessId Source #
Returns the ProcessId of the current process.
isProcessAlive :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => SchedulerProxy q -> ProcessId -> Eff r Bool Source #
Return True if the process is alive.
Since: 0.12.0
Spawning
spawn :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => Eff (InterruptableProcess q) () -> Eff r ProcessId Source #
Start a new process, the new process will execute an effect, the function
will return immediately with a ProcessId. If the new process is
interrupted, the process will Shutdown with the InterruptReason
wrapped in NotCovered. For specific use cases it might be better to use
spawnRaw.
spawn_ :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => Eff (InterruptableProcess q) () -> Eff r () Source #
Like spawn but return ().
spawnLink :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => Eff (InterruptableProcess q) () -> Eff r ProcessId Source #
Start a new process, and immediately link to it.
Since: 0.12.0
spawnRaw :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => Eff (ConsProcess q) () -> Eff r ProcessId Source #
Start a new process, the new process will execute an effect, the function
will return immediately with a ProcessId. The spawned process has only the
raw ConsProcess effects. For non-library code spawn might be better
suited.
spawnRaw_ :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => Eff (ConsProcess q) () -> Eff r () Source #
Like spawnRaw but return ().
Process Exit or Interrupt
exitBecause :: forall r q a. (HasCallStack, SetMember Process (Process q) r) => SchedulerProxy q -> ExitReason NoRecovery -> Eff r a Source #
Exit the process with a ProcessExitReaon.
exitNormally :: forall r q a. (HasCallStack, SetMember Process (Process q) r) => SchedulerProxy q -> Eff r a Source #
Exit the process.
exitWithError :: forall r q a. (HasCallStack, SetMember Process (Process q) r) => SchedulerProxy q -> String -> Eff r a Source #
Exit the process with an error.
Links
linkProcess :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => SchedulerProxy q -> ProcessId -> Eff r () Source #
Connect the calling process to another process, such that
if one of the processes crashes (i.e. isCrash returns True), the other
is shutdown with the ProcessExitReaon LinkedProcessCrashed.
Since: 0.12.0
unlinkProcess :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => SchedulerProxy q -> ProcessId -> Eff r () Source #
Unlink the calling proccess from the other process.
Since: 0.12.0
Monitors
monitor :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => SchedulerProxy q -> ProcessId -> Eff r MonitorReference Source #
Monitor another process. When the monitored process exits a
ProcessDown is sent to the calling process.
The return value is a unique identifier for that monitor.
There can be multiple monitors on the same process,
and a message for each will be sent.
If the process is already dead, the ProcessDown message
will be sent immediately, w.thout exit reason
Since: 0.12.0
demonitor :: forall r q. (HasCallStack, SetMember Process (Process q) r, Member Interrupts r) => SchedulerProxy q -> MonitorReference -> Eff r () Source #
Remove a monitor created with monitor.
Since: 0.12.0
data ProcessDown Source #
A monitored process exited.
This message is sent to a process by the scheduler, when
a process that was monitored via a SchedulerCommand died.
Since: 0.12.0
Constructors
| ProcessDown | |
Fields | |
Instances
selectProcessDown :: MonitorReference -> MessageSelector ProcessDown Source #
A MesssageSelector for the ProcessDown message of a specific
process.
Since: 0.12.0
becauseProcessIsDown :: ProcessDown -> InterruptReason Source #
Trigger an Interrupt for a ProcessDown message.
The reason will be ProcessNotRunning
Since: 0.12.0
data MonitorReference Source #
A value that contains a unique reference of a process monitoring.
Since: 0.12.0
Constructors
| MonitorReference | |
Fields | |
Instances
withMonitor :: (HasCallStack, Member Interrupts r, SetMember Process (Process q) r, Member Interrupts r) => SchedulerProxy q -> ProcessId -> (MonitorReference -> Eff r a) -> Eff r a Source #
receiveWithMonitor :: (HasCallStack, Member Interrupts r, SetMember Process (Process q) r, Member Interrupts r, Typeable a, Show a) => SchedulerProxy q -> ProcessId -> MessageSelector a -> Eff r (Either ProcessDown a) Source #
A MessageSelector for receiving either a monitor of the
given process or another message.
Since: 0.12.0
Process Interrupt Handling
provideInterruptsShutdown :: forall e a. Eff (InterruptableProcess e) a -> Eff (ConsProcess e) a Source #
Handle all InterruptReasons of an InterruptableProcess by
wrapping them up in NotRecovered and then do a process Shutdown.
handleInterrupts :: (HasCallStack, Member Interrupts r) => (InterruptReason -> Eff r a) -> Eff r a -> Eff r a Source #
Handle InterruptReasons arising during process operations, e.g.
when a linked process crashes while we wait in a receiveSelectedMessage
via a call to interrupt.
exitOnInterrupt :: (HasCallStack, Member Interrupts r, SetMember Process (Process q) r) => SchedulerProxy q -> Eff r a -> Eff r a Source #
Handle InterruptReasons arising during process operations, e.g.
when a linked process crashes while we wait in a receiveSelectedMessage
via a call to interrupt.
logInterrupts :: (HasCallStack, '[Interrupts, Logs LogMessage] <:: r) => Eff r () -> Eff r () Source #
Handle interrupts by logging them with logProcessExit and otherwise
ignoring them.
provideInterrupts :: HasCallStack => Eff (Interrupts ': r) a -> Eff r (Either InterruptReason a) Source #
Handle InterruptReasons arising during process operations, e.g.
when a linked process crashes while we wait in a receiveSelectedMessage
via a call to interrupt.
mergeEitherInterruptAndExitReason :: Either InterruptReason (ExitReason NoRecovery) -> ExitReason NoRecovery Source #
Wrap all (left) InterruptReasons into NotRecovered and
return the (right) NoRecovery ExitReasons as is.
interrupt :: (HasCallStack, Member Interrupts r) => InterruptReason -> Eff r a Source #
Throw an InterruptReason, can be handled by recoverFromInterrupt or
exitOnInterrupt or provideInterrupts.
Process Operation Execution
executeAndResume :: forall q r v. (SetMember Process (Process q) r, HasCallStack) => Process q (ResumeProcess v) -> Eff r (Either (ExitReason Recoverable) v) Source #
Execute a and action and return the result;
if the process is interrupted by an error or exception, or an explicit
shutdown from another process, or through a crash of a linked process, i.e.
whenever the exit reason satisfies isRecoverable, return the exit reason.
executeAndResumeOrExit :: forall r q v. (SetMember Process (Process q) r, HasCallStack) => Process q (ResumeProcess v) -> Eff r v Source #
Execute a Process action and resume the process, exit
the process when an Interrupts was raised. Use executeAndResume to catch
interrupts.
executeAndResumeOrThrow :: forall q r v. (SetMember Process (Process q) r, HasCallStack, Member Interrupts r) => Process q (ResumeProcess v) -> Eff r v Source #
Execute a Process action and resume the process, exit
the process when an Interrupts was raised. Use executeAndResume to catch
interrupts.
Exit Or Interrupt Reasons
data ExitReason (t :: ExitRecovery) where Source #
A sum-type with reasons for why a process exists the scheduling loop, this includes errors, that can occur when scheduleing messages.
Constructors
| ProcessNotRunning :: ProcessId -> ExitReason Recoverable | A process that should be running was not running. |
| LinkedProcessCrashed :: ProcessId -> ExitReason Recoverable | A linked process is down |
| ProcessError :: String -> ExitReason Recoverable | An exit reason that has an error message but isn't |
| ExitNormally :: ExitReason NoRecovery | A process function returned or exited without any error. |
| NotRecovered :: ExitReason Recoverable -> ExitReason NoRecovery | An unhandled |
| UnexpectedException :: String -> String -> ExitReason NoRecovery | An unexpected runtime exception was thrown, i.e. an exception
derived from |
| Killed :: ExitReason NoRecovery | A process was cancelled (e.g. killed, in |
Instances
data ExitRecovery Source #
This kind is used to indicate if a ExitReason can be treated like
a short interrupt which can be handled or ignored.
Constructors
| Recoverable | |
| NoRecovery |
Instances
| Eq ExitRecovery Source # | |
Defined in Control.Eff.Concurrent.Process | |
| Ord ExitRecovery Source # | |
Defined in Control.Eff.Concurrent.Process Methods compare :: ExitRecovery -> ExitRecovery -> Ordering # (<) :: ExitRecovery -> ExitRecovery -> Bool # (<=) :: ExitRecovery -> ExitRecovery -> Bool # (>) :: ExitRecovery -> ExitRecovery -> Bool # (>=) :: ExitRecovery -> ExitRecovery -> Bool # max :: ExitRecovery -> ExitRecovery -> ExitRecovery # min :: ExitRecovery -> ExitRecovery -> ExitRecovery # | |
| Show ExitRecovery Source # | |
Defined in Control.Eff.Concurrent.Process Methods showsPrec :: Int -> ExitRecovery -> ShowS # show :: ExitRecovery -> String # showList :: [ExitRecovery] -> ShowS # | |
| Generic ExitRecovery Source # | |
Defined in Control.Eff.Concurrent.Process Associated Types type Rep ExitRecovery :: Type -> Type # | |
| NFData ExitRecovery Source # | |
Defined in Control.Eff.Concurrent.Process Methods rnf :: ExitRecovery -> () # | |
| type Rep ExitRecovery Source # | |
Defined in Control.Eff.Concurrent.Process | |
type InterruptReason = ExitReason Recoverable Source #
ExitReasons which are recoverable are interrupts.
type Interrupts = Exc InterruptReason Source #
Exceptions containing InterruptReasons.
See handleInterrupts, exitOnInterrupt or provideInterrupts
type InterruptableProcess e = Interrupts ': ConsProcess e Source #
This adds a layer of the Interrupts effect ontop of ConsProcess
data ExitSeverity Source #
This value indicates wether a process exited in way consistent with the planned behaviour or not.
Constructors
| NormalExit | |
| Crash |
Instances
| Eq ExitSeverity Source # | |
Defined in Control.Eff.Concurrent.Process | |
| Ord ExitSeverity Source # | |
Defined in Control.Eff.Concurrent.Process Methods compare :: ExitSeverity -> ExitSeverity -> Ordering # (<) :: ExitSeverity -> ExitSeverity -> Bool # (<=) :: ExitSeverity -> ExitSeverity -> Bool # (>) :: ExitSeverity -> ExitSeverity -> Bool # (>=) :: ExitSeverity -> ExitSeverity -> Bool # max :: ExitSeverity -> ExitSeverity -> ExitSeverity # min :: ExitSeverity -> ExitSeverity -> ExitSeverity # | |
| Show ExitSeverity Source # | |
Defined in Control.Eff.Concurrent.Process Methods showsPrec :: Int -> ExitSeverity -> ShowS # show :: ExitSeverity -> String # showList :: [ExitSeverity] -> ShowS # | |
| Generic ExitSeverity Source # | |
Defined in Control.Eff.Concurrent.Process Associated Types type Rep ExitSeverity :: Type -> Type # | |
| NFData ExitSeverity Source # | |
Defined in Control.Eff.Concurrent.Process Methods rnf :: ExitSeverity -> () # | |
| type Rep ExitSeverity Source # | |
Defined in Control.Eff.Concurrent.Process | |
data SomeExitReason where Source #
An existential wrapper around ExitReason
Constructors
| SomeExitReason :: ExitReason x -> SomeExitReason |
Instances
| Eq SomeExitReason Source # | |
Defined in Control.Eff.Concurrent.Process Methods (==) :: SomeExitReason -> SomeExitReason -> Bool # (/=) :: SomeExitReason -> SomeExitReason -> Bool # | |
| Ord SomeExitReason Source # | |
Defined in Control.Eff.Concurrent.Process Methods compare :: SomeExitReason -> SomeExitReason -> Ordering # (<) :: SomeExitReason -> SomeExitReason -> Bool # (<=) :: SomeExitReason -> SomeExitReason -> Bool # (>) :: SomeExitReason -> SomeExitReason -> Bool # (>=) :: SomeExitReason -> SomeExitReason -> Bool # max :: SomeExitReason -> SomeExitReason -> SomeExitReason # min :: SomeExitReason -> SomeExitReason -> SomeExitReason # | |
| Show SomeExitReason Source # | |
Defined in Control.Eff.Concurrent.Process Methods showsPrec :: Int -> SomeExitReason -> ShowS # show :: SomeExitReason -> String # showList :: [SomeExitReason] -> ShowS # | |
| NFData SomeExitReason Source # | |
Defined in Control.Eff.Concurrent.Process Methods rnf :: SomeExitReason -> () # | |
toExitRecovery :: ExitReason r -> ExitRecovery Source #
Get the ExitRecovery
isRecoverable :: ExitReason x -> Bool Source #
A predicate for recoverable exit reasons. This predicate defines the
exit reasonson which functions such as executeAndResume
toExitSeverity :: ExitReason e -> ExitSeverity Source #
Get the ExitSeverity of a ExitReason.
isBecauseDown :: Maybe ProcessId -> ExitReason r -> Bool Source #
A predicate for linked process crashes.
isCrash :: ExitReason x -> Bool Source #
A predicate for crashes. A crash happens when a process exits
with an ExitReason other than ExitNormally
toCrashReason :: ExitReason x -> Maybe String Source #
Print a ExitReason to Just a formatted String when isCrash
is True.
This can be useful in combination with view patterns, e.g.:
logCrash :: ExitReason -> Eff e () logCrash (toCrashReason -> Just reason) = logError reason logCrash _ = return ()
Though this can be improved to:
logCrash = traverse_ logError . toCrashReason
fromSomeExitReason :: SomeExitReason -> Either (ExitReason NoRecovery) InterruptReason Source #
Partition a SomeExitReason back into either a NoRecovery
or a Recoverable ExitReason
logProcessExit :: (HasCallStack, Member (Logs LogMessage) e) => ExitReason x -> Eff e () Source #
Log the ProcessExitReaons