Skip to content

Migrate indexHieFile progress notification to ProgressReporting API #4205

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

Merged

Conversation

soulomoon
Copy link
Collaborator

@soulomoon soulomoon commented May 2, 2024

What's done

  1. Refactor ProgressReporting to allow external state management
  2. Migrate indexHieFile progress to ProgressReporting API
  3. Add Note [ProgressReporting API and InProgressState] to demonstrate the current status

@soulomoon soulomoon force-pushed the soulomoon/wait-for-token-indexHieFile branch from 1440f35 to d70acdb Compare May 2, 2024 23:36
@soulomoon soulomoon changed the title Wait For token using Barrier when indexHieFile Wait for progress token using Barrier when indexHieFile May 3, 2024
@soulomoon soulomoon marked this pull request as ready for review May 3, 2024 01:21
@soulomoon soulomoon requested a review from pepeiborra as a code owner May 3, 2024 01:21
@soulomoon soulomoon requested review from wz1000, michaelpj and fendor May 3, 2024 01:21
@michaelpj
Copy link
Collaborator

Could we refactor this to actually use the helpers from lsp for running progress sessions? I think that should handle all of this properly, rather than us re-implementing it here?

@wz1000
Copy link
Collaborator

wz1000 commented May 3, 2024

This code manages its progress token in a somewhat unique way which is not easy to statically scope with the lsp progress functions.

_ <- LSP.sendRequest LSP.SMethod_WindowWorkDoneProgressCreate (LSP.WorkDoneProgressCreateParams u) (const $ pure ())
b <- liftIO newBarrier
void $ LSP.sendRequest LSP.SMethod_WindowWorkDoneProgressCreate (LSP.WorkDoneProgressCreateParams u) $ liftIO . signalBarrier b
ready <- liftIO $ waitBarrier b
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know if its a good idea to delay indexing by an unbounded amount of time waiting for the client to respond with a progress token. Perhaps the progress reporting should be on another thread which doesn't block indexing.

Copy link
Collaborator Author

@soulomoon soulomoon May 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, but indexHieFile would return without reportProgress actually report done🤔. I am not sure how does it do to our test, I'll see how it goes.

@soulomoon
Copy link
Collaborator Author

soulomoon commented May 3, 2024

Instead of a long runner task, it is more like tunes of small tasks dynamically created only finished when the all the pendding tasks are done. Hard to fit this in helpers from lsp.
But we still can if we are handling this in a seperate thread, might need serveral pipes though. And hard to say if it would make thing simpler🤔

@soulomoon soulomoon marked this pull request as draft May 4, 2024 13:43
@soulomoon soulomoon marked this pull request as ready for review May 4, 2024 23:43
@soulomoon
Copy link
Collaborator Author

soulomoon commented May 4, 2024

I've spawn a new thread to run the indexing progress update, send through TQueue. 🤔 Is it a good idea to do so?

@soulomoon soulomoon added the status: in discussion Not actionable, because discussion is still ongoing or there's no decision yet label May 5, 2024
@michaelpj
Copy link
Collaborator

I think we can probably do something like #4218 now

@soulomoon
Copy link
Collaborator Author

soulomoon commented Jun 12, 2024

I think we can probably do something like #4218 now

It seems, here we are using a push update model.
And in #4218, it is a pull update model for every interval.
Maybe we can unify to use a pull update model?

Also, I am wondering if we can make Development.IDE.Core.ProgressReporting more general, so we can actually reuse it.

@michaelpj
Copy link
Collaborator

Also, I am wondering if we can make Development.IDE.Core.ProgressReporting more general, so we can actually reuse it.

Yes, I think there's almost something there. It's something like a standalone counter that also has some triggers for killing and restarting it?

@soulomoon soulomoon force-pushed the soulomoon/wait-for-token-indexHieFile branch from 56f43e6 to 54fdce3 Compare June 13, 2024 08:34
@soulomoon soulomoon force-pushed the soulomoon/wait-for-token-indexHieFile branch from 54fdce3 to 8981601 Compare June 13, 2024 08:38
Copy link
Collaborator

@michaelpj michaelpj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks plausible, I wonder if we can simplify ProgressReporting and just have one way to do it.


data ProgressEvent
= KickStarted
| KickCompleted
= ProgressStarted
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Nothing -> do
tt <- progressReportingOutsideState
(liftM2 (+) (HashMap.size <$> readTVar indexPending) (readTVar indexCompleted))
(readTVar indexCompleted)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems a bit backwards to me? Can we not use the usual ProgressReporting and then call progressUpdate etc. instead of touching these TVars in the indexing code?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I think I get it. Now I wonder if it would be simpler to make the other progress tracker work this way?

Copy link
Collaborator Author

@soulomoon soulomoon Jun 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As along as they are already tracking the progress status external at some T*** varaibles.

But I take a look at the use case at kick, the state(todo count,done count) tracking is at defineEarlyCutoff' and independent for each file. No easy way to switch the Kick progress tracker work this way.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, but when we create the progress tracker we could set that stuff up externally, so that the ProgressReporting doesn't see it. Let me see if I can just write it down.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here: 2ad92a0

If we did this then I think indexHieFile could just use progressCounter directly?

Copy link
Collaborator Author

@soulomoon soulomoon Jun 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, I've extracted it to standalone now
@michaelpj


I'll see if it fit in.

Copy link
Collaborator Author

@soulomoon soulomoon Jun 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

then I think if you export it you can just use it in indexHieFile

If using it barely in indexHieFile, we still need some kind of wrapping around progressCounter. async and cancel the progressCounter.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, we do need that. But we could just do it locally. Or maybe you want to have a standalone concept of a "resumable/cancellable progress counter" and then just put the file-tracking on top for the compilation progress tracker?

Copy link
Collaborator Author

@soulomoon soulomoon Jun 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be the latter, I am moving up the indexHieFile reporting initialization to shakeOpen as that of the Kick reporting. Should be much cleaner than the preivous version.

Copy link
Collaborator Author

@soulomoon soulomoon Jun 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"resumable/cancellable progress counter" need an additional start Event that won't replace the existing progress reporting.

= KickStarted
| KickCompleted
= ProgressStarted
| ProgressCompleted
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just get rid of progressStop, given that it just does the same thing as progressUpdate ProgressCompleted?

Copy link
Collaborator Author

@soulomoon soulomoon Jun 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Kick progress tracking working differently than indexHIeFile.

HLS begins: Progress tracking started

  • loop:
    • Kick start ProgressStarted
    • Kick end ProgressCompleted

HLS shutdown: Progress tracking Stop

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yes, I missed that the state update is different, ProgressCompleted goes back to NotStarted. It's not clear that that gets us much, though 🤔

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NotStarted and Stopped are the same state, except you can't start again from Stopped. But why does that even matter? In both cases you stop the session, it's not like Stopped cleans up any more resources!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the way it is structured we get a restartable progress tracker, which is a reasonable thing to have when you keep a single reference to it alive for a long time.. But I think it could be simpler.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the way it is structured we get a restartable progress tracker

Yes, I think it is intended for multiple Kick's.

Copy link
Collaborator Author

@soulomoon soulomoon Jun 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or we need to initialize progress tracker at each kick.

So basically:
restartable wrapped progress tracker versus progress tracker used only once.

Copy link
Collaborator Author

@soulomoon soulomoon Jun 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess, Stopped state is intended to forbit us to start the progress tracker again after the we shutdown hls

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That doesn't seem actually useful, though. I'd be inclined to remove it.

@soulomoon
Copy link
Collaborator Author

soulomoon commented Jun 17, 2024

Now it becomes resumable/restartable/cancellable progress reporting

We might want to renamed that

  • ProgressStarted -> ProgressNewStarted: cancel the old one
  • ProgressTryToStart -> ProgressStarted: won't cancel the old one

@soulomoon
Copy link
Collaborator Author

soulomoon commented Jun 18, 2024

After introducing new event capturing more progress reporting logic, we are able to change the indexProgressToken :: Var (Maybe LSP.ProgressToken) to indexProgressReporting :: ProgressReporting IO. Ready to be reviewed again @michaelpj

@soulomoon soulomoon requested a review from michaelpj June 18, 2024 13:57
Copy link
Collaborator

@michaelpj michaelpj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, maybe just write down some of what we've learned!

= KickStarted
| KickCompleted
= ProgressStarted
| ProgressCompleted
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That doesn't seem actually useful, though. I'd be inclined to remove it.

doneVar :: TVar Int,
currentVar :: STM.Map NormalizedFilePath Int
}
| InProgressStateOutSide
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still find this split a bit weird, but we've spent enough time on this!

Copy link
Collaborator Author

@soulomoon soulomoon Jun 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, especially we have inProgress that is useless InProgressStateOutSide.
Maybe in some following ups, we can come up with alternative design such as using GADTs to eliminate this discrepancy

, _percentage = Nothing
}

pre = progressUpdate indexProgressReporting ProgressStarted
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had actually thought we could just initialize a progressCounter here and use it just in the scope of this function, but this works too!

@michaelpj
Copy link
Collaborator

Needs conflicts fixed then good to go

@soulomoon soulomoon changed the title Wait for progress token using Barrier when indexHieFile Migrate indexHieFile progress notification to ProgressReporting API Jun 20, 2024
@soulomoon soulomoon enabled auto-merge (squash) June 20, 2024 17:00
@soulomoon soulomoon added merge me Label to trigger pull request merge and removed merge me Label to trigger pull request merge status: needs review This PR is ready for review labels Jun 20, 2024
@soulomoon soulomoon merged commit f523690 into haskell:master Jun 20, 2024
36 checks passed
dsaenztagarro added a commit to dsaenztagarro/haskell-language-server that referenced this pull request Jun 26, 2024
* master: (36 commits)
  Migrate indexHieFile progress notification to ProgressReporting API (haskell#4205)
  Remove final allow-newer for 9.10 (haskell#4329)
  Remove unused exactprint dep
  More stylish
  Use newer cabal-fmt, partially lift ghc version restriction
  stylish
  Cleanup CI configs and cabal files
  More no-op code cleanup
  Remove no-longer-needed compat code, remove unused stuff
  Remove pre-multi component junk for GHC <= 9.2
  Fix stylish
  Fix a few things
  Remove from CI
  Update docs
  Fix loss of 9.2 GHC version
  More CPP
  WIP evaluate CPP
  Prepare release 2.9.0.0 (haskell#4319)
  Add completion for import fields in cabal files (haskell#4305)
  Refine GHC deprecation policy (haskell#3438)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants