Skip to content
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

Record duration of total compilation #19

Open
parsonsmatt opened this issue Jan 30, 2024 · 3 comments · May be fixed by #21
Open

Record duration of total compilation #19

parsonsmatt opened this issue Jan 30, 2024 · 3 comments · May be fixed by #21

Comments

@parsonsmatt
Copy link
Contributor

The code to create a span says that it is not in general possible to know when compilation has completed. This is true. While we can/should extend the plugin API to have a hook for "on compilation completion," it may also be possible to record an approximation of this.

Right now, we're using hotel-california to record the entire time spent in the make build process. But this includes the time spent in cabal and the time spent reading interface files etc in GHC before we even start compiling. So there's some ambiguity anyway with that span.

Options (all bad/need further investigation)

addFinalizer

One (bad) option is to use addFinalizer. This has a big caveat - the Implementation Notes section calls out that the GC may not be run on program exit, and that's exactly what we're trying to determine. If we had a way to install a hook to do a GC before exit, then we'd also have the ability to just close the span directly.

Root Modules

One option is to use the "root modules" as an approximation. This is the code for that. There's an existing caveat that we don't know which root module is the last to be compiled. If we could figure that out, then we'd have a decent way of determining a way to do that.

I don't think we can rely on root modules being compiled close to each other in time. Imagine a package with root modules A and B. A depends on modules in A.{A0 - A10}, and should finish compiling relatively quickly. But B depends on B.{B0 - B1000}, and will take much longer. Both A and B are root modules, but A should complete faster, and so we can't just have a "tickler" that starts a timer every time a root module is compiled (and then closes the span whenever the time limit is reached for other root modules to complete).

The ModuleGraph type contains a list of ModuleGraphNode. Perhaps we could dig in here to determine root with the largest dependency graph?

@Gabriella439
Copy link
Collaborator

Yeah, I already looked into addFinalizer and passed on that for the reason mentioned: it doesn't guarantee to run on program exit. I even verified that this is the case on a test program (it did indeed not run on exit).

@parsonsmatt parsonsmatt linked a pull request Jan 31, 2024 that will close this issue
@parsonsmatt
Copy link
Contributor Author

Loking into the module graph...

topSortModuleGraph gives us a [SCC ModuleGraphNode], where a ModuleGraphNode, and the ModuleNode has a ModSummary, which has a Module, which has a ModuleName.

We already record the root modules, so what we want to do is figure out which root module is the "last" one to compile. That ought to be the last one in the [SCC ModuleGraphNode].

I think we need to additionally check to see if the module failed to compile in a given phase - which means we need to solve #7 too lol

@parsonsmatt
Copy link
Contributor Author

I created a GHC feature request for this: https://gitlab.haskell.org/ghc/ghc/-/issues/24402

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 a pull request may close this issue.

2 participants