-
-
Notifications
You must be signed in to change notification settings - Fork 367
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Stabilize the build system by correctly house keeping the dirtykeys and rule values [flaky test #4185 #4093] #4190
Stabilize the build system by correctly house keeping the dirtykeys and rule values [flaky test #4185 #4093] #4190
Conversation
So basically we don't want to delete the dirty keys outside the |
We might have dirty key lost if we are marking them as dirty in shakeExtra when the shake session is running. That is we are marking those keys that are already running in session as dirty. Then when they are done running, they remove themself from the dirty set. |
Another option would be to expand the state of keys in shakeExtra to have three state |
This PR seems to have a bunch of unrelated changes. Could you also write down a commit message explaining the problem and solution when you find the time please? |
Yes, that could also work. So then if a rule finishes it updates the state to 'clean' if it was 'running', but not if it has been set back to 'dirty' while it was in progress. |
This PR is a proof of concept to fix the problem we have encounter at #4185 for now. Sorry I forget to addresss that, addressed now #4190 (comment) and unrelated changes are removed. |
590e71b
to
684a850
Compare
I review relevant part a bit, it seems to be hard to do so, since a lot of IO is entangling |
684a850
to
52f85b2
Compare
The third solution. This seems to have the least changed, I have pushed this branch. But a slightly altered version, book keeping an extra runningKeys TVar. Just a few lines of code have changed. |
That's kind of you to say that, but it's just good old "printf debugging", I wish I knew how to do it more ergonomically 😄 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was wondering about writing a test for this, and that made me wonder why dirtiness checking isn't part of hls-graph
, where it would be easier to test in isolation. Does anyone know?
In fact Why do we have two versions of this? :( |
And indeed, it already correctly handles this case! https://github.com/haskell/haskell-language-server/blob/master/hls-graph/src/Development/IDE/Graph/Internal/Database.hs#L75 |
@@ -474,10 +474,9 @@ loadSessionWithOptions recorder SessionLoadingOptions{..} dir = do | |||
clientConfig <- getClientConfigAction | |||
extras@ShakeExtras{restartShakeSession, ideNc, knownTargetsVar, lspEnv | |||
} <- getShakeExtras | |||
let invalidateShakeCache :: IO () | |||
invalidateShakeCache = do | |||
let invalidateShakeCache = do | |||
void $ modifyVar' version succ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be moved out of the restart.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome work and investigation! This should make HLS much more robust.
A thought: can we delegate more to
That means we never need to "clean" a key on our side, and so we can drop (some of?) the To elaborate a bit: the reason we need If we need access to the set of "dirty keys this session" then we can also store what |
Yes,this seems to be a potential improvement to do as a follow up to this PR. We can see how it would fit into the monitoring and garbage collect stuff by then |
Okay, I'm happy for you to look into this more after this PR! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Few stylistic suggestions, otherwise LGTM
-- Note [Housekeeping rule cache and dirty key out side of hls-graph] | ||
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
-- Hls-graph contains its own internal running state for each key in the shakeDatabase. | ||
-- Rule result cache and dirty key are in ShakeExtras that is not visible to the hls-graph |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not clear to me which field in ShakeExtras represents rule result cache.
Could you please mention it here?
-- Rule result cache and dirty key are in ShakeExtras that is not visible to the hls-graph | |
-- ShakeExtras contains ??? field (rule result cache) and dirtyKeys (keys that became dirty in between build sessions) that is not visible to the hls-graph |
Co-authored-by: Jan Hrcek <[email protected]>
Co-authored-by: Jan Hrcek <[email protected]>
Co-authored-by: Jan Hrcek <[email protected]>
Co-authored-by: Jan Hrcek <[email protected]>
Co-authored-by: Jan Hrcek <[email protected]>
Co-authored-by: Jan Hrcek <[email protected]>
Co-authored-by: Jan Hrcek <[email protected]>
Co-authored-by: Jan Hrcek <[email protected]>
What is currently did up to 240254e
The main problem is the out of sync state in the build system. Several states involved, the shake database running result state for key. shake extra's dirty state for key and shake extra's rule values state.
To stablize the build system. This PR force some of the updates of these state into a single STM block.
GetLinkable
#4093 [Verified fixed locally 500 rounds]RunResult
. Properly handle the dirtykeys and rule value state after session start and closely followed by another session restart Fixing ghcide-tests'addDependentFile
test #4194 [Verified fixed locally 500 rounds]asyncWithCleanUp
torefreshDeps
possible future improvement (Should be in some other PR)
*. we can avoid giving multiple update to dirty states across multiple session if the key is still dirty but does not marked as new dirty, by sending the collected keys directly to newsession. But
garbageCollectKeys
is using it, so it is not a good idea to do it now. Maybe in the future.*. Maybe we can schedule some debouncer to the session restart. I've observed some times the consective session restart might happen.
The problem
Some proof of concept for fixing problem at #4185 #4093 discovered and tracked down by @jhrcek with his impressive bug tracking technique.
Here should be what might be happeing for the problem:
The essential problem is that a running key is being marked as dirty, and finished running and removed itself from the dirtyset in shakeExtra just before a sessionRestart flush it to rerun in the hls-graph database, and hence the dirty mark is incorrectly lost.
The worm bed is that we are bookkeeping two set of dirtiness, one in hls-graph database(has three states, running, dity, clean) and one in shake-extra(two states, dirty, clean).
It is nasty to keep them in sync.
Possible fixes
Some possible solutions:
We are passing keys need to be updated directly to the
restartShakeSession
instead of just recording it in the dirtykeys ofshakeExtra
. Which keep them from being removed right before the restartShakeSession.But might need to track out each such case and safe guard them to restartShakeSession.
when mark the dirtykeys in
shakeExtra
, we also mark them inshakeDatabase
, but we might need to dirty all its reversedeps to make sure it would break dirtiness of them, I do not see how much better can this be better than shakerestartWhen keys being added to dirtykeys in
shakeExtra
, we restart the shake session at the same time, leaving no gap in between. @michaelpj 'idea that we can use VarT instead of MVar and wrap the key changed and session restart both togather.we add a running state for keys innot workable since the update have to be in hls-graphshakeExtra
, avoid remove the dirtykeys inshakeExtra
if the running state is gone. Or some thing similar to expand the possible state that can be represent inshakeExtra
. We might need extra book keeping a lot more keys. but simplestzcreate a new temp dirtykeyset to record new dirty keys, and only flush it to dirtykeyset inside
restartShakeSession