feat: faster dependency computation #33

Open
raito wants to merge 1 commit from faster-depinfo into forkos

View file

@ -7,7 +7,7 @@ import base64
from collections.abc import Generator from collections.abc import Generator
from dataclasses import dataclass, field from dataclasses import dataclass, field
from pathlib import Path from pathlib import Path
from typing import Any from typing import Any, NamedTuple
import buildbot import buildbot
from buildbot.configurators import ConfiguratorBase from buildbot.configurators import ConfiguratorBase
@ -41,6 +41,12 @@ MasterLock = util.MasterLock
FLAKE_TARGET_ATTRIBUTE_FOR_JOBS = "hydraJobs" FLAKE_TARGET_ATTRIBUTE_FOR_JOBS = "hydraJobs"
class Job(NamedTuple):
commit: str
name: str
expensive: bool
deps: set[str] = set()
@dataclass @dataclass
class EvaluatorSettings: class EvaluatorSettings:
supported_systems: list[str] supported_systems: list[str]
@ -425,12 +431,15 @@ class NixEvalCommand(buildstep.ShellMixin, steps.BuildStep):
drv_show_log: StreamLog = yield self.getLog("stdio") drv_show_log: StreamLog = yield self.getLog("stdio")
all_deps = dict() all_deps = dict()
def closure_of(key, deps): def find_deps(drv_info: dict[Any, Any]) -> dict[str, set[str]]:
r, size = set([key]), 0 deps = {}
while len(r) != size: for drv, info in drv_info.items():
size = len(r) deps[drv] = set(info["inputDrvs"].keys())
r.update(*[ deps[k] for k in r ]) for n in graphlib.TopologicalSorter(deps).static_order():
return r.difference([key]) for d in tuple(deps[n]):
deps[n].update(deps[d])
return deps
if succeeded_jobs: if succeeded_jobs:
drv_show_log.addStdout(f"getting derivation infos for valid derivations\n") drv_show_log.addStdout(f"getting derivation infos for valid derivations\n")
@ -449,11 +458,8 @@ class NixEvalCommand(buildstep.ShellMixin, steps.BuildStep):
except json.JSONDecodeError as e: except json.JSONDecodeError as e:
msg = f"Failed to parse `nix derivation show` output for {cmd.command}" msg = f"Failed to parse `nix derivation show` output for {cmd.command}"
raise BuildbotNixError(msg) from e raise BuildbotNixError(msg) from e
for drv, info in drv_info.items():
all_deps[drv] = set(info.get("inputDrvs").keys())
job_set = set(( drv for drv in ( job.get("drvPath") for job in filtered_jobs ) if drv )) all_deps = find_deps(drv_info)
all_deps = { k: list(closure_of(k, all_deps).intersection(job_set)) for k in job_set }
self.build.addStepsAfterCurrentStep( self.build.addStepsAfterCurrentStep(
[ [