conio
Safe HaskellNone
LanguageGHC2021

ConIO.Core

Synopsis

Concurrent IO

data ConIO a Source #

ConIO stands for concurrent IO. ConIO works like normal IO, but you can also fork off threads without worry. Threads launched within ConIO will never outlive the ConIO scope. Before ConIO ends, it will wait for all threads to finish or cancel them. Additionally, exceptions between parent and children are propagated per default, completely shutting down all processes when an exception happens anywhere.

You do not have to worry about:

  • Zombie processes, since a thread can never outlive its parent scope.
  • Dead processes, since exceptions will propagate to the parent thread.

Instances

Instances details
MonadIO ConIO Source # 
Instance details

Defined in ConIO.Core

Methods

liftIO :: IO a -> ConIO a #

MonadSTM ConIO Source # 
Instance details

Defined in ConIO.Core

Methods

liftSTM :: STM a -> ConIO a Source #

liftSTM_IO :: STM a -> IO a -> ConIO a Source #

Applicative ConIO Source # 
Instance details

Defined in ConIO.Core

Methods

pure :: a -> ConIO a #

(<*>) :: ConIO (a -> b) -> ConIO a -> ConIO b #

liftA2 :: (a -> b -> c) -> ConIO a -> ConIO b -> ConIO c #

(*>) :: ConIO a -> ConIO b -> ConIO b #

(<*) :: ConIO a -> ConIO b -> ConIO a #

Functor ConIO Source # 
Instance details

Defined in ConIO.Core

Methods

fmap :: (a -> b) -> ConIO a -> ConIO b #

(<$) :: a -> ConIO b -> ConIO a #

Monad ConIO Source # 
Instance details

Defined in ConIO.Core

Methods

(>>=) :: ConIO a -> (a -> ConIO b) -> ConIO b #

(>>) :: ConIO a -> ConIO b -> ConIO b #

return :: a -> ConIO a #

MonadFail ConIO Source # 
Instance details

Defined in ConIO.Core

Methods

fail :: String -> ConIO a #

MonadFix ConIO Source # 
Instance details

Defined in ConIO.Core

Methods

mfix :: (a -> ConIO a) -> ConIO a #

runConIO :: MonadIO m => ConIO a -> m a Source #

Opens up a concurrent scope by running ConIO. No threads launched within ConIO outlive this scope, since it waits for them to finish.

runConIOCancel :: MonadIO m => ConIO a -> m a Source #

Opens up a concurrent scope by running 'ConIO. Cancels all tasks before returning.

Tasks

data Task a Source #

A Task represents a thread which is producing some a. You can wait for tasks or cancel them.

The internals of Task are exposed if you need them. However, this ought not to be necessary.

Constructors

Task 

Fields

Instances

Instances details
Applicative Task Source # 
Instance details

Defined in ConIO.Core

Methods

pure :: a -> Task a #

(<*>) :: Task (a -> b) -> Task a -> Task b #

liftA2 :: (a -> b -> c) -> Task a -> Task b -> Task c #

(*>) :: Task a -> Task b -> Task b #

(<*) :: Task a -> Task b -> Task a #

Functor Task Source # 
Instance details

Defined in ConIO.Core

Methods

fmap :: (a -> b) -> Task a -> Task b #

(<$) :: a -> Task b -> Task a #

launch :: IO a -> ConIO (Task a) Source #

launch is the main way to spin up new threads. It will execute the given action in another thread and returns a Task.

wait :: MonadSTM m => Task a -> m a Source #

Wait for a Task and return its payload.

cancel :: MonadIO m => Task a -> m () Source #

Cancel a Task, killing all threads which are part of producing the a value. cancel returns immediately and does not wait for the canceled threads to die.

If you want to wait for threads to die, you need to start them in a separate scope.

If you cancel a Task which comprises other ones (e.g. by using <*>), it will cancel the contained tasks.

cancelAll :: ConIO () Source #

Cancel the whole scope, killing all spawned threads and disabling the ConIO scope. You cannot launch any more threads from a disabled ConIO scope.

linkTasks :: Task a -> Task b -> Task b Source #

Create a new task which produces the same result as task b. When you cancel the new task, you cancel both task a and task b.

Manage scopes

data ConScope (s :: k) Source #

A ConIO scope which can be passed around

withConScope :: (forall (s :: k). ConScope s -> IO a) -> ConIO a Source #

Get the ConIO scope and use it in an internal computation. The `forall s.` prevents incorrect usage of the scope.

useConScope :: forall {k} (s :: k) a. ConScope s -> ConIO a -> IO a Source #

Use the ConScope to run a ConIO in the original scope.

data UnsafeConScope Source #

An UnsafeConScope has no forall quantifier, making it possible for scopes to escape their originating ConIO. Use this only if you know what you are doing.

toUnsafeConScope :: forall {k} (s :: k). ConScope s -> UnsafeConScope Source #

fromUnsafeConScope :: UnsafeConScope -> (forall (s :: k). ConScope s -> a) -> a Source #

Exceptions

data ConIOException Source #

ConIOException is used for all exceptions related to threads created by launch.

Constructors

ConIODisabled

Happens when you try to launch from within a disabled environment

ConIOTaskException SomeException

Happens when a child thread throws an exception

data ConIOKillThread Source #

The ConIOKillThread exception is used internally to kill threads without bringing down the whole ConIO scope.

Do not catch this exception, unless you know what you are doing. Keep in mind to rethrow AsyncException if you catch SomeException!

A normal SIGKILL triggered by the external system will shutdown the whole ConIO scope.

Constructors

ConIOKillThread