haskell / haskell/cabal

Don't re-run the solver unnecessarily

Open
#12,119 2 comments 2 reactions 0 assignees View on GitHub
attention: pr-welcome cabal-install: cmd/build recompilation type: bug type: discussion type: performance
Dominant language
Haskell
Stars
1.7k
Forks
750
Avg merge
4d 3h
Merged PRs (30d)
28

Description

The recompilation logic for the solver triggers recompilation if anything in the package description changes. See `Distribution.Client.ProjectPlanning.rebuildInstallPlan`:

```hs
phaseRunSolver
:: ProjectConfig
-> (Compiler, Platform, ProgramDb)
-> [PackageSpecifier UnresolvedSourcePackage]
-> InstalledPackageIndex
-> Rebuild (SolverInstallPlan, Maybe PkgConfigDb, IndexUtils.TotalIndexState, IndexUtils.ActiveRepos)
phaseRunSolver
projectConfig@ProjectConfig
{ projectConfigShared
, projectConfigBuildOnly
}
(compiler, platform, progdb)
localPackages
installedPackages =
rerunIfChanged
verbosity
fileMonitorSolverPlan
( solverSettings
, localPackages -- !!!
, localPackagesEnabledStanzas
, compiler
, platform
, programDbSignature progdb
)
$ do ...
```

We re-run the solver if `localPackages` changes, and this includes all the fields of `SourcePackage`, including **the entire `GenericPackageDescription`**!!!

```hs
data SourcePackage loc = SourcePackage
{ srcpkgPackageId :: PackageId
, srcpkgDescription :: GenericPackageDescription
, srcpkgSource :: loc
, srcpkgDescrOverride :: PackageDescriptionOverride
}
deriving (Eq, Show, Generic)
```

The principled way to fix this would be to change the input of the solver entirely. The solver only needs the information that's in the `Distribution.Solver.Modular.Index.PInfo` datatype:

```hs
data PInfo = PInfo (FlaggedDeps PN)
(Map ExposedComponent ComponentInfo)
FlagInfo
(Maybe FailReason)

data ComponentInfo = ComponentInfo {
compIsVisible :: IsVisible
, compIsBuildable :: IsBuildable
}
```

We should project down to these `PInfo`s instead of passing `SourcePackage`s that contain full package description. This will require reworking consumers of the `solverPkgSource` constructed by `Distribution.Solver.Modular.ConfiguredConversion.convCP` which uses the solver result to modify `SourcePackage`s.

Contributor guide

Open the contributing guide

Research direction

Start in Distribution.Client.ProjectPlanning.rebuildInstallPlan, especially phaseRunSolver and its localPackages input, then inspect Distribution.Solver.Modular.Index.PInfo and ConfiguredConversion.convCP. Trace consumers of solverPkgSource and verify that solver reruns no longer depend on unrelated GenericPackageDescription changes while the solver result still updates SourcePackages correctly.

Written by the indexing model from the issue text.

Assessment

Tech stack
haskell
Domain
build-system
Issue type
Refactor
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.