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
f22237c7
Commit
f22237c7
authored
3 years ago
by
Jens Nolte
Browse files
Options
Downloads
Patches
Plain Diff
Simplify RootResourceManager
parent
7b605952
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Pipeline
#2510
passed
3 years ago
Changes
1
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/Quasar/ResourceManager.hs
+30
-39
30 additions, 39 deletions
src/Quasar/ResourceManager.hs
with
30 additions
and
39 deletions
src/Quasar/ResourceManager.hs
+
30
−
39
View file @
f22237c7
...
@@ -244,64 +244,55 @@ instance Exception CombinedException where
...
@@ -244,64 +244,55 @@ instance Exception CombinedException where
exceptionMessages
=
(
displayException
<$>
toList
exceptions
)
exceptionMessages
=
(
displayException
<$>
toList
exceptions
)
data
RootResourceManagerState
=
RootResourceManagerNormal
|
RootResourceManagerDisposing
|
RootResourceManagerDisposed
deriving
stock
Eq
data
RootResourceManager
data
RootResourceManager
=
RootResourceManager
=
RootResourceManager
ResourceManager
(
TVar
Bool
)
(
TVar
(
Maybe
(
Seq
SomeException
)))
(
Awaitable
()
)
ResourceManager
(
TVar
RootResourceManagerState
)
(
TVar
(
Seq
SomeException
))
(
Awaitable
()
)
instance
IsResourceManager
RootResourceManager
where
instance
IsResourceManager
RootResourceManager
where
attachDisposable
(
RootResourceManager
child
_
_
_
)
disposable
=
attachDisposable
child
disposable
attachDisposable
(
RootResourceManager
child
_
_
_
)
disposable
=
attachDisposable
child
disposable
throwToResourceManager
(
RootResourceManager
_
state
Var
exceptionsVar
_
)
ex
=
do
throwToResourceManager
(
RootResourceManager
_
disposing
Var
exceptionsVar
_
)
ex
=
do
-- TODO only log exceptions
when disposing does not finish in
time
-- TODO only log exceptions
after a
time
out
traceIO
$
"Exception thrown to root resource manager: "
<>
displayException
ex
traceIO
$
"Exception thrown to root resource manager: "
<>
displayException
ex
disposed
<-
liftIO
$
atomically
do
liftIO
$
join
$
atomically
do
state
<-
readTVar
stateVar
stateTVar
exceptionsVar
\
case
-- Start disposing
Just
exceptions
->
(
pure
()
,
Just
(
exceptions
|>
toException
ex
))
when
(
state
==
RootResourceManagerNormal
)
$
writeTVar
stateVar
RootResourceManagerDisposing
Nothing
->
(
fail
@
IO
"Could not throw to resource manager: RootResourceManager is already disposed"
,
Nothing
)
let
disposed
=
state
==
RootResourceManagerDisposed
unless
disposed
$
modifyTVar
exceptionsVar
(
|>
toException
ex
)
pure
disposed
when
disposed
$
fail
"Could not throw to resource manager: RootResourceManager is already disposed"
instance
IsDisposable
RootResourceManager
where
instance
IsDisposable
RootResourceManager
where
dispose
(
RootResourceManager
_
stateVar
_
isDisposedAwaitable
)
=
do
dispose
(
RootResourceManager
_
disposingVar
_
isDisposedAwaitable
)
=
liftIO
do
liftIO
$
atomically
do
isDisposedAwaitable
<$
atomically
do
state
<-
readTVar
stateVar
disposing
<-
readTVar
disposingVar
-- Start disposing
unless
disposing
$
writeTVar
disposingVar
True
when
(
state
==
RootResourceManagerNormal
)
$
writeTVar
stateVar
RootResourceManagerDisposing
pure
isDisposedAwaitable
isDisposed
(
RootResourceManager
_
_
_
isDisposedAwaitable
)
=
isDisposedAwaitable
isDisposed
(
RootResourceManager
_
_
_
isDisposedAwaitable
)
=
isDisposedAwaitable
newUnmanagedRootResourceManager
::
MonadIO
m
=>
m
ResourceManager
newUnmanagedRootResourceManager
::
MonadIO
m
=>
m
ResourceManager
newUnmanagedRootResourceManager
=
liftIO
$
toResourceManager
<$>
do
newUnmanagedRootResourceManager
=
liftIO
$
toResourceManager
<$>
do
state
Var
<-
newTVarIO
RootResourceManagerNormal
disposing
Var
<-
newTVarIO
False
exceptionsVar
<-
newTVarIO
Empty
exceptionsVar
<-
newTVarIO
(
Just
Empty
)
mfix
\
root
->
do
mfix
\
root
->
do
isDisposedAwaitable
<-
toAwaitable
<$>
unmanagedFork
(
disposeThread
root
)
isDisposedAwaitable
<-
toAwaitable
<$>
unmanagedFork
(
disposeThread
root
)
child
<-
newUnmanagedDefaultResourceManager
(
toResourceManager
root
)
child
<-
newUnmanagedDefaultResourceManager
(
toResourceManager
root
)
pure
$
RootResourceManager
child
stateVar
exceptionsVar
isDisposedAwaitable
pure
$
RootResourceManager
child
disposingVar
exceptionsVar
isDisposedAwaitable
where
where
disposeThread
::
RootResourceManager
->
IO
()
disposeThread
::
RootResourceManager
->
IO
()
disposeThread
(
RootResourceManager
child
stateVar
exceptionsVar
_
)
=
do
disposeThread
(
RootResourceManager
child
disposingVar
exceptionsVar
_
)
=
do
-- Wait until disposing
atomically
do
atomically
do
state
<-
readTVar
stateVar
disposing
<-
readTVar
disposingVar
when
(
state
==
RootResourceManagerNormal
)
retry
hasExceptions
<-
(
>
0
)
.
Seq
.
length
<$>
(
maybe
impossibleCodePathM
pure
=<<
readTVar
exceptionsVar
)
-- TODO start thread: wait for timeout, then report exceptions or report hang
check
$
disposing
||
hasExceptions
-- TODO start the thread that reports exceptions (or a potential hang) after a timeout
await
=<<
dispose
child
await
=<<
dispose
child
atomically
do
exceptions
<-
nonEmpty
.
toList
<$>
readTVar
exceptionsVar
mExceptions
<-
atomically
do
mapM_
(
throwM
.
CombinedException
)
exceptions
-- The var is set to `Nothing` to signal that no more exceptions can be received
nonEmpty
.
toList
<$>
(
maybe
impossibleCodePathM
pure
=<<
swapTVar
exceptionsVar
Nothing
)
-- If there are any exceptions will be stored in the awaitable (isDisposedAwaitable) by throwing them here
mapM_
(
throwM
.
CombinedException
)
mExceptions
withRootResourceManager
::
(
MonadAwait
m
,
MonadMask
m
,
MonadIO
m
)
=>
ReaderT
ResourceManager
IO
a
->
m
a
withRootResourceManager
::
(
MonadAwait
m
,
MonadMask
m
,
MonadIO
m
)
=>
ReaderT
ResourceManager
IO
a
->
m
a
...
...
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