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
c7c31854
Commit
c7c31854
authored
3 years ago
by
Jens Nolte
Browse files
Options
Downloads
Patches
Plain Diff
Change exported querySTM signature to safer variant
parent
3cf499ee
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/Quasar/Awaitable.hs
+19
-12
19 additions, 12 deletions
src/Quasar/Awaitable.hs
with
19 additions
and
12 deletions
src/Quasar/Awaitable.hs
+
19
−
12
View file @
c7c31854
module
Quasar.Awaitable
(
-- * Awaitable
IsAwaitable
(
..
),
MonadQuerySTM
(
..
),
MonadQuerySTM
(
querySTM
),
awaitIO
,
peekAwaitable
,
Awaitable
,
...
...
@@ -53,7 +53,6 @@ class IsAwaitable r a | a -> r where
toAwaitable
::
a
->
Awaitable
r
toAwaitable
=
Awaitable
{-# MINIMAL toAwaitable | (runAwaitable, cacheAwaitable) #-}
...
...
@@ -114,24 +113,32 @@ successfulAwaitable = completedAwaitable . Right
failedAwaitable
::
SomeException
->
Awaitable
r
failedAwaitable
=
completedAwaitable
.
Left
-- | Create an awaitable from a `STM` transaction.
-- | Create an awaitable from a
n
`STM` transaction.
--
-- Use `retry` to signal that the awaitable is not yet completed and `throwM`/`throwSTM` to set the awaitable to failed.
simpleAwaitable
::
STM
a
->
Awaitable
a
simpleAwaitable
query
=
toAwaitable
$
FnAwaitable
$
querySTM
do
(
Just
.
Right
<$>
query
)
`
orElse
`
pure
Nothing
(
Right
<$>
query
)
`
catchAll
`
\
ex
->
pure
(
Just
(
Left
ex
)
)
\
ex
->
pure
(
Left
ex
)
mapAwaitable
::
IsAwaitable
i
a
=>
(
Either
SomeException
i
->
Either
SomeException
r
)
->
a
->
Awaitable
r
mapAwaitable
fn
awaitable
=
toAwaitable
$
FnAwaitable
$
fn
<$>
runAwaitable
awaitable
class
Monad
m
=>
MonadQuerySTM
m
where
querySTM
::
(
forall
a
.
STM
(
Maybe
a
)
->
m
a
)
-- | Run an `STM` transaction. `retry` can be used.
querySTM
::
(
forall
a
.
STM
a
->
m
a
)
querySTM
transaction
=
unsafeQuerySTM
$
(
Just
<$>
transaction
)
`
orElse
`
pure
Nothing
-- | Run an "STM` transaction. `retry` MUST NOT be used
unsafeQuerySTM
::
(
forall
a
.
STM
(
Maybe
a
)
->
m
a
)
unsafeQuerySTM
transaction
=
querySTM
$
maybe
retry
pure
=<<
transaction
{-# MINIMAL querySTM | unsafeQuerySTM #-}
instance
Monad
m
=>
MonadQuerySTM
(
ReaderT
(
QueryFn
m
)
m
)
where
q
uerySTM
query
=
do
unsafeQ
uerySTM
query
=
do
QueryFn
querySTMFn
<-
ask
lift
$
querySTMFn
query
...
...
@@ -151,7 +158,7 @@ instance IsAwaitable r (CachedAwaitable r) where
runAwaitable
(
CachedAwaitable
tvar
)
=
go
where
go
::
m
(
Either
SomeException
r
)
go
=
q
uerySTM
stepCacheTransaction
>>=
\
case
go
=
unsafeQ
uerySTM
stepCacheTransaction
>>=
\
case
AwaitableCompleted
result
->
pure
result
-- Cached operation is not yet completed
_
->
go
...
...
@@ -191,7 +198,7 @@ instance Monad AwaitableStepM where
(
AwaitableStep
query
next
)
>>=
fn
=
AwaitableStep
query
(
next
>=>
fn
)
instance
MonadQuerySTM
AwaitableStepM
where
q
uerySTM
query
=
AwaitableStep
query
AwaitableCompleted
unsafeQ
uerySTM
query
=
AwaitableStep
query
AwaitableCompleted
-- ** AsyncVar
...
...
@@ -200,7 +207,7 @@ instance MonadQuerySTM AwaitableStepM where
newtype
AsyncVar
r
=
AsyncVar
(
TMVar
(
Either
SomeException
r
))
instance
IsAwaitable
r
(
AsyncVar
r
)
where
runAwaitable
(
AsyncVar
var
)
=
q
uerySTM
$
tryReadTMVar
var
runAwaitable
(
AsyncVar
var
)
=
unsafeQ
uerySTM
$
tryReadTMVar
var
cacheAwaitable
=
pure
.
toAwaitable
...
...
@@ -247,7 +254,7 @@ awaitEither x y = toAwaitable $ FnAwaitable $ groupLefts <$> stepBoth (runAwaita
stepBoth
(
AwaitableCompleted
resultX
)
_
=
pure
$
Left
resultX
stepBoth
_
(
AwaitableCompleted
resultY
)
=
pure
$
Right
resultY
stepBoth
stepX
@
(
AwaitableStep
transactionX
nextX
)
stepY
@
(
AwaitableStep
transactionY
nextY
)
=
do
q
uerySTM
(
peekEitherSTM
transactionX
transactionY
)
>>=
\
case
unsafeQ
uerySTM
(
peekEitherSTM
transactionX
transactionY
)
>>=
\
case
Left
resultX
->
stepBoth
(
nextX
resultX
)
stepY
Right
resultY
->
stepBoth
stepX
(
nextY
resultY
)
...
...
@@ -268,7 +275,7 @@ awaitAny xs = toAwaitable $ FnAwaitable $ stepAll Empty Empty $ runAwaitable <$>
do
prevSteps
|>
step
steps
stepAll
acc
ps
Empty
=
do
newAwaitableSteps
<-
q
uerySTM
$
maybe
impossibleCodePathM
peekAnySTM
$
nonEmpty
(
toList
acc
)
newAwaitableSteps
<-
unsafeQ
uerySTM
$
maybe
impossibleCodePathM
peekAnySTM
$
nonEmpty
(
toList
acc
)
stepAll
Empty
Empty
newAwaitableSteps
...
...
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