Skip to content

Commit db050f2

Browse files
committed
Parallelize installations
1 parent 0b486c7 commit db050f2

2 files changed

Lines changed: 72 additions & 13 deletions

File tree

src/porcelain/install.test.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1-
import { useTestConfig } from "../hooks/useTestConfig.ts"
21
import { assert, assertArrayIncludes } from "deno/testing/asserts.ts"
3-
import { ConsoleLogger } from "../plumbing/install.ts"
4-
import type { Package } from "../types.ts";
5-
import type { Resolution } from "../plumbing/resolve.ts";
2+
import { useTestConfig } from "../hooks/useTestConfig.ts"
3+
import type { Resolution } from "../plumbing/resolve.ts"
4+
import install, { ConsoleLogger } from "./install.ts"
65
import * as semver from "../utils/semver.ts"
7-
import install from "./install.ts"
6+
import type { Package } from "../types.ts"
87

98
Deno.test("porcelain.install.1", async () => {
109
useTestConfig()

src/porcelain/install.ts

Lines changed: 68 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import install, { Logger as InstallLogger } from "../plumbing/install.ts"
1+
import install, { Logger as BaseLogger, ConsoleLogger as BaseConsoleLogger } from "../plumbing/install.ts"
22
import { Installation, PackageSpecification } from "../types.ts"
33
import resolve, { Resolution } from "../plumbing/resolve.ts"
44
import usePantry from "../hooks/usePantry.ts"
@@ -9,8 +9,21 @@ import link from "../plumbing/link.ts"
99
import { is_what } from "../deps.ts"
1010
const { isString } = is_what
1111

12-
export interface Logger extends InstallLogger {
12+
export interface Logger extends BaseLogger {
1313
resolved?(resolution: Resolution): void
14+
/// from 0.0–1.0
15+
/// currently you won’t get this immediately since we are waiting for all our
16+
/// network requests to return before we know the final download size
17+
progress?(completion: number): void
18+
}
19+
20+
// deno-lint-ignore no-explicit-any
21+
export function ConsoleLogger(prefix?: any): Logger {
22+
prefix = prefix ? `${prefix}: ` : ""
23+
return {
24+
...BaseConsoleLogger(prefix),
25+
progress: function() { console.error(`${prefix}progress`, ...arguments) },
26+
}
1427
}
1528

1629
/// eg. install("python.org~3.10")
@@ -31,12 +44,59 @@ export default async function(pkgs: PackageSpecification[] | string[] | string,
3144
const resolution = await resolve(pkgs)
3245
logger?.resolved?.(resolution)
3346

34-
const { pending, installed} = resolution
35-
for (const pkg of pending) {
36-
const installation = await install(pkg, logger)
37-
await link(installation)
38-
installed.push(installation)
39-
}
47+
const { pending, installed } = resolution
48+
logger = WrapperLogger(pending, logger)
49+
const installers = pending
50+
.map(pkg => install(pkg, logger)
51+
.then(i => link(i).then(() => i)))
52+
53+
installed.push(...await Promise.all(installers))
4054

4155
return installed
4256
}
57+
58+
function WrapperLogger(pending: PackageSpecification[], logger?: Logger): Logger | undefined {
59+
if (!logger?.progress) return logger
60+
61+
const projects = pending.map(pkg => pkg.project)
62+
const totals: Record<string, number> = {}
63+
const progresses: Record<string, number> = {}
64+
return {
65+
...logger,
66+
downloading: args => {
67+
const { pkg: {project}, total } = args
68+
if (total) {
69+
totals[project] = total
70+
updateProgress()
71+
}
72+
if (logger?.downloading) {
73+
logger.downloading(args)
74+
}
75+
},
76+
installing: args => {
77+
const { pkg: {project}, progress } = args
78+
if (progress) {
79+
progresses[project] = progress
80+
updateProgress()
81+
}
82+
if (logger?.installing) {
83+
logger.installing(args)
84+
}
85+
}
86+
}
87+
88+
function updateProgress() {
89+
let total_untard_bytes = 0
90+
let grand_total = 0
91+
for (const project of projects) {
92+
const total = totals[project]
93+
const bytes = progresses[project] * total
94+
total_untard_bytes += bytes
95+
grand_total += total
96+
}
97+
const rv = total_untard_bytes / grand_total
98+
if (!isNaN(rv)) {
99+
logger!.progress!(total_untard_bytes / grand_total)
100+
}
101+
}
102+
}

0 commit comments

Comments
 (0)