Skip to content
Snippets Groups Projects
Commit c143b320 authored by Jens Nolte's avatar Jens Nolte
Browse files

Move Task to Quasar.Disposable module

parent 3b110430
No related branches found
No related tags found
No related merge requests found
...@@ -5,19 +5,6 @@ module Quasar.Async ( ...@@ -5,19 +5,6 @@ module Quasar.Async (
async_, async_,
asyncWithUnmask_, asyncWithUnmask_,
-- * Task
Task,
cancelTask,
cancelTaskIO,
toTask,
completedTask,
successfulTask,
failedTask,
-- ** Task exceptions
CancelTask(..),
TaskDisposed(..),
-- * Unmanaged forking -- * Unmanaged forking
forkTask, forkTask,
forkTask_, forkTask_,
...@@ -155,52 +142,3 @@ forkTaskWithUnmask_ action = toDisposable <$> forkTaskWithUnmask action ...@@ -155,52 +142,3 @@ forkTaskWithUnmask_ action = toDisposable <$> forkTaskWithUnmask action
-- | A task that is running asynchronously. It has a result and can fail.
-- The result (or exception) can be aquired by using the `IsAwaitable` class (e.g. by calling `await` or `awaitIO`).
-- It might be possible to cancel the task by using the `IsDisposable` class if the operation has not been completed.
-- If the result is no longer required the task should be cancelled, to avoid leaking memory.
data Task r = Task Disposable (Awaitable r)
instance IsAwaitable r (Task r) where
toAwaitable (Task _ awaitable) = awaitable
instance IsDisposable (Task r) where
toDisposable (Task disposable _) = disposable
instance Functor Task where
fmap fn (Task disposable awaitable) = Task disposable (fn <$> awaitable)
instance Applicative Task where
pure value = Task noDisposable (pure value)
liftA2 fn (Task dx fx) (Task dy fy) = Task (dx <> dy) $ liftA2 fn fx fy
cancelTask :: Task r -> IO (Awaitable ())
cancelTask = dispose
cancelTaskIO :: Task r -> IO ()
cancelTaskIO = await <=< dispose
-- | Creates an `Task` from an `Awaitable`.
-- The resulting task only depends on an external resource, so disposing it has no effect.
toTask :: IsAwaitable r a => a -> Task r
toTask result = Task noDisposable (toAwaitable result)
completedTask :: Either SomeException r -> Task r
completedTask result = Task noDisposable (completedAwaitable result)
-- | Alias for `pure`
successfulTask :: r -> Task r
successfulTask = pure
failedTask :: SomeException -> Task r
failedTask ex = Task noDisposable (failedAwaitable ex)
data CancelTask = CancelTask
deriving stock Show
instance Exception CancelTask where
data TaskDisposed = TaskDisposed
deriving stock Show
instance Exception TaskDisposed where
...@@ -21,6 +21,19 @@ module Quasar.Disposable ( ...@@ -21,6 +21,19 @@ module Quasar.Disposable (
attachDisposeAction, attachDisposeAction,
attachDisposeAction_, attachDisposeAction_,
disposeEventually, disposeEventually,
-- * Task
Task(..),
cancelTask,
toTask,
completedTask,
successfulTask,
failedTask,
-- ** Task exceptions
CancelTask(..),
TaskDisposed(..),
) where ) where
import Control.Concurrent (forkIOWithUnmask) import Control.Concurrent (forkIOWithUnmask)
...@@ -402,3 +415,57 @@ disposeEventually resourceManager disposable = liftIO $ do ...@@ -402,3 +415,57 @@ disposeEventually resourceManager disposable = liftIO $ do
peekAwaitable disposeCompleted >>= \case peekAwaitable disposeCompleted >>= \case
Just () -> pure () Just () -> pure ()
Nothing -> attachDisposable resourceManager disposable Nothing -> attachDisposable resourceManager disposable
-- | A task is an operation (e.g. a thread or a network request) that is running asynchronously and can be cancelled.
-- It has a result and can fail.
--
-- The result (or exception) can be aquired by using the `IsAwaitable` class (e.g. by calling `await` or `awaitIO`).
-- It is possible to cancel the task by using `dispose` or `cancelTask` if the operation has not been completed.
data Task r = Task Disposable (Awaitable r)
instance IsAwaitable r (Task r) where
toAwaitable (Task _ awaitable) = awaitable
instance IsDisposable (Task r) where
toDisposable (Task disposable _) = disposable
instance Functor Task where
fmap fn (Task disposable awaitable) = Task disposable (fn <$> awaitable)
instance Applicative Task where
pure value = Task noDisposable (pure value)
liftA2 fn (Task dx fx) (Task dy fy) = Task (dx <> dy) $ liftA2 fn fx fy
-- | Alias for `dispose`.
cancelTask :: Task r -> IO (Awaitable ())
cancelTask = dispose
-- | Creates an `Task` from an `Awaitable`.
-- The resulting task only depends on an external resource, so disposing it has no effect.
toTask :: IsAwaitable r a => a -> Task r
toTask result = Task noDisposable (toAwaitable result)
completedTask :: Either SomeException r -> Task r
completedTask result = Task noDisposable (completedAwaitable result)
-- | Alias for `pure`
successfulTask :: r -> Task r
successfulTask = pure
failedTask :: SomeException -> Task r
failedTask ex = Task noDisposable (failedAwaitable ex)
data CancelTask = CancelTask
deriving stock Show
instance Exception CancelTask where
data TaskDisposed = TaskDisposed
deriving stock Show
instance Exception TaskDisposed where
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment