Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Q
quasar
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Jens Nolte
quasar
Commits
744ca563
Commit
744ca563
authored
3 years ago
by
Jens Nolte
Browse files
Options
Downloads
Patches
Plain Diff
Add cacheAwaitable to IsAwaitable class
parent
dbd4fdbb
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/Quasar/Awaitable.hs
+44
-21
44 additions, 21 deletions
src/Quasar/Awaitable.hs
src/Quasar/Disposable.hs
+2
-0
2 additions, 0 deletions
src/Quasar/Disposable.hs
with
46 additions
and
21 deletions
src/Quasar/Awaitable.hs
+
44
−
21
View file @
744ca563
...
...
@@ -12,7 +12,6 @@ module Quasar.Awaitable (
mapAwaitable
,
-- * Awaiting multiple awaitables
cacheAwaitable
,
awaitEither
,
awaitAny
,
...
...
@@ -28,6 +27,9 @@ module Quasar.Awaitable (
failAsyncVar_
,
putAsyncVarEither_
,
putAsyncVarEitherSTM_
,
-- * Implementation helpers
cacheAwaitableDefaultImplementation
,
)
where
import
Control.Concurrent.STM
...
...
@@ -44,10 +46,14 @@ class IsAwaitable r a | a -> r where
runAwaitable
::
(
MonadQuerySTM
m
)
=>
a
->
m
(
Either
SomeException
r
)
runAwaitable
self
=
runAwaitable
(
toAwaitable
self
)
cacheAwaitable
::
MonadIO
m
=>
a
->
m
(
Awaitable
r
)
cacheAwaitable
self
=
cacheAwaitable
(
toAwaitable
self
)
toAwaitable
::
a
->
Awaitable
r
toAwaitable
x
=
Awaitable
$
runAwaitable
x
toAwaitable
=
Awaitable
{-# MINIMAL toAwaitable | runAwaitable #-}
{-# MINIMAL toAwaitable |
(
runAwaitable
, cacheAwaitable)
#-}
awaitIO
::
(
IsAwaitable
r
a
,
MonadIO
m
)
=>
a
->
m
r
...
...
@@ -57,22 +63,23 @@ peekAwaitable :: (IsAwaitable r a, MonadIO m) => a -> m (Maybe (Either SomeExcep
peekAwaitable
awaitable
=
liftIO
$
runMaybeT
$
runQueryT
(
MaybeT
.
atomically
)
(
runAwaitable
awaitable
)
newtype
Awaitable
r
=
Awaitable
(
forall
m
.
(
MonadQuerySTM
m
)
=>
m
(
Either
SomeException
r
))
data
Awaitable
r
=
forall
a
.
IsAwaitable
r
a
=>
Awaitable
a
instance
IsAwaitable
r
(
Awaitable
r
)
where
runAwaitable
(
Awaitable
x
)
=
x
runAwaitable
(
Awaitable
x
)
=
runAwaitable
x
cacheAwaitable
(
Awaitable
x
)
=
cacheAwaitable
x
toAwaitable
=
id
instance
Functor
Awaitable
where
fmap
fn
(
Awaitable
x
)
=
Awaitable
$
fn
<<$>>
x
fmap
fn
(
Awaitable
x
)
=
toAwaitable
$
Fn
Awaitable
$
fn
<<$>>
runAwaitable
x
instance
Applicative
Awaitable
where
pure
value
=
Awaitable
$
pure
(
Right
value
)
liftA2
fn
(
Awaitable
fx
)
(
Awaitable
fy
)
=
Awaitable
$
liftA2
(
liftA2
fn
)
fx
fy
pure
value
=
toAwaitable
$
Fn
Awaitable
$
pure
(
Right
value
)
liftA2
fn
(
Awaitable
fx
)
(
Awaitable
fy
)
=
toAwaitable
$
Fn
Awaitable
$
liftA2
(
liftA2
fn
)
(
runAwaitable
fx
)
(
runAwaitable
fy
)
instance
Monad
Awaitable
where
(
Awaitable
fx
)
>>=
fn
=
Awaitable
$
do
fx
>>=
\
case
(
Awaitable
fx
)
>>=
fn
=
toAwaitable
$
Fn
Awaitable
$
do
runAwaitable
fx
>>=
\
case
Left
ex
->
pure
$
Left
ex
Right
x
->
runAwaitable
(
fn
x
)
...
...
@@ -83,9 +90,22 @@ instance Monoid r => Monoid (Awaitable r) where
mempty
=
pure
mempty
newtype
FnAwaitable
r
=
FnAwaitable
(
forall
m
.
(
MonadQuerySTM
m
)
=>
m
(
Either
SomeException
r
))
instance
IsAwaitable
r
(
FnAwaitable
r
)
where
runAwaitable
(
FnAwaitable
x
)
=
x
cacheAwaitable
=
cacheAwaitableDefaultImplementation
newtype
CompletedAwaitable
r
=
CompletedAwaitable
(
Either
SomeException
r
)
instance
IsAwaitable
r
(
CompletedAwaitable
r
)
where
runAwaitable
(
CompletedAwaitable
x
)
=
pure
x
cacheAwaitable
=
pure
.
toAwaitable
completedAwaitable
::
Either
SomeException
r
->
Awaitable
r
completedAwaitable
result
=
Awaitable
$
pur
e
result
completedAwaitable
result
=
to
Awaitable
$
CompletedAwaitabl
e
result
successfulAwaitable
::
r
->
Awaitable
r
successfulAwaitable
=
completedAwaitable
.
Right
...
...
@@ -94,10 +114,10 @@ failedAwaitable :: SomeException -> Awaitable r
failedAwaitable
=
completedAwaitable
.
Left
simpleAwaitable
::
STM
(
Maybe
(
Either
SomeException
a
))
->
Awaitable
a
simpleAwaitable
query
=
Awaitable
(
querySTM
query
)
simpleAwaitable
query
=
to
Awaitable
$
FnAwaitable
$
querySTM
query
mapAwaitable
::
IsAwaitable
i
a
=>
(
Either
SomeException
i
->
Either
SomeException
r
)
->
a
->
Awaitable
r
mapAwaitable
fn
awaitable
=
Awaitable
$
fn
<$>
runAwaitable
awaitable
mapAwaitable
fn
awaitable
=
to
Awaitable
$
FnAwaitable
$
fn
<$>
runAwaitable
awaitable
class
Monad
m
=>
MonadQuerySTM
m
where
...
...
@@ -116,8 +136,8 @@ runQueryT queryFn action = runReaderT action (QueryFn queryFn)
newtype
CachedAwaitable
r
=
CachedAwaitable
(
TVar
(
AwaitableStepM
(
Either
SomeException
r
)))
cacheAwaitable
::
Awaitable
a
->
IO
(
Cached
Awaitable
a
)
cacheAwaitable
awaitable
=
CachedAwaitable
<$>
newTVarIO
(
runAwaitable
awaitable
)
cacheAwaitable
DefaultImplementation
::
(
Is
Awaitable
r
a
,
MonadIO
m
)
=>
a
->
m
(
Awaitable
r
)
cacheAwaitable
DefaultImplementation
awaitable
=
toAwaitable
.
CachedAwaitable
<$>
liftIO
(
newTVarIO
(
runAwaitable
awaitable
)
)
instance
IsAwaitable
r
(
CachedAwaitable
r
)
where
runAwaitable
::
forall
m
.
(
MonadQuerySTM
m
)
=>
CachedAwaitable
r
->
m
(
Either
SomeException
r
)
...
...
@@ -137,13 +157,16 @@ instance IsAwaitable r (CachedAwaitable r) where
AwaitableStep
query
fn
->
do
-- Run the next "querySTM" query requested by the cached operation
fn
<<$>>
query
>>=
\
case
-- In case of an incomplete query the caller (/ the monad `m`) can decide what to do (e.g. retry for `awaitIO`, abort for `peekAwaitable`)
-- In case of an incomplete query the caller (/ the monad `m`) can decide what to do (e.g. retry for
-- `awaitIO`, abort for `peekAwaitable`)
Nothing
->
pure
Nothing
-- Query was successful. Update cache and exit query
Just
nextStep
->
do
writeTVar
tvar
nextStep
pure
$
Just
nextStep
cacheAwaitable
=
pure
.
toAwaitable
data
AwaitableStepM
a
=
AwaitableCompleted
a
|
forall
b
.
AwaitableStep
(
STM
(
Maybe
b
))
(
b
->
AwaitableStepM
a
)
...
...
@@ -171,6 +194,7 @@ newtype AsyncVar r = AsyncVar (TMVar (Either SomeException r))
instance
IsAwaitable
r
(
AsyncVar
r
)
where
runAwaitable
(
AsyncVar
var
)
=
querySTM
$
tryReadTMVar
var
cacheAwaitable
=
pure
.
toAwaitable
newAsyncVarSTM
::
STM
(
AsyncVar
r
)
...
...
@@ -209,8 +233,8 @@ putAsyncVarEitherSTM_ var = void . putAsyncVarEitherSTM var
-- * Awaiting multiple asyncs
awaitEither
::
(
IsAwaitable
ra
a
,
IsAwaitable
rb
b
,
MonadIO
m
)
=>
a
->
b
->
m
(
Awaitable
(
Either
ra
rb
)
)
awaitEither
x
y
=
pur
e
$
Awaitable
$
groupLefts
<$>
stepBoth
(
runAwaitable
x
)
(
runAwaitable
y
)
awaitEither
::
(
IsAwaitable
ra
a
,
IsAwaitable
rb
b
)
=>
a
->
b
->
Awaitable
(
Either
ra
rb
)
awaitEither
x
y
=
toAwaitabl
e
$
Fn
Awaitable
$
groupLefts
<$>
stepBoth
(
runAwaitable
x
)
(
runAwaitable
y
)
where
stepBoth
::
MonadQuerySTM
m
=>
AwaitableStepM
ra
->
AwaitableStepM
rb
->
m
(
Either
ra
rb
)
stepBoth
(
AwaitableCompleted
resultX
)
_
=
pure
$
Left
resultX
...
...
@@ -221,8 +245,8 @@ awaitEither x y = pure $ Awaitable $ groupLefts <$> stepBoth (runAwaitable x) (r
Right
resultY
->
stepBoth
stepX
(
nextY
resultY
)
awaitAny
::
(
IsAwaitable
r
a
,
MonadIO
m
)
=>
NonEmpty
a
->
m
(
Awaitable
r
)
awaitAny
xs
=
pur
e
$
Awaitable
$
stepAll
Empty
Empty
$
runAwaitable
<$>
fromList
(
toList
xs
)
awaitAny
::
IsAwaitable
r
a
=>
NonEmpty
a
->
Awaitable
r
awaitAny
xs
=
toAwaitabl
e
$
Fn
Awaitable
$
stepAll
Empty
Empty
$
runAwaitable
<$>
fromList
(
toList
xs
)
where
stepAll
::
MonadQuerySTM
m
...
...
@@ -253,7 +277,6 @@ peekEitherSTM x y =
Just
r
->
pure
(
Just
(
Right
r
))
Nothing
->
pure
Nothing
peekAnySTM
::
NonEmpty
(
STM
(
Maybe
a
))
->
STM
(
Maybe
a
)
peekAnySTM
(
x
:|
xs
)
=
x
>>=
\
case
r
@
(
Just
_
)
->
pure
r
...
...
This diff is collapsed.
Click to expand it.
src/Quasar/Disposable.hs
+
2
−
0
View file @
744ca563
...
...
@@ -91,6 +91,8 @@ instance IsAwaitable () FnDisposable where
-- Query if dispose is completed
runAwaitable
awaitable
cacheAwaitable
=
cacheAwaitableDefaultImplementation
data
CombinedDisposable
=
CombinedDisposable
Disposable
Disposable
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment