Skip to content

Commit

Permalink
feat: add runInBand for better debugging (#212)
Browse files Browse the repository at this point in the history
* feat: add runInBand for better debugging

* fix: add copyright
  • Loading branch information
Diego Ferreiro Val authored Oct 28, 2019
1 parent 8a62a4b commit e739ee4
Show file tree
Hide file tree
Showing 12 changed files with 139 additions and 42 deletions.
2 changes: 1 addition & 1 deletion packages/@best/builder/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"mkdirp": "~0.5.1",
"ncp": "^2.0.0",
"rimraf": "^2.6.2",
"rollup": "~1.25.2",
"rollup": "~1.26.0",
"rollup-plugin-compat": "^0.21.7",
"worker-farm": "~1.7.0"
},
Expand Down
21 changes: 20 additions & 1 deletion packages/@best/builder/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { FrozenGlobalConfig, FrozenProjectConfig, BuildConfig } from '@best/type
import { BuildOutputStream } from "@best/console-stream";
import { isCI } from '@best/utils';
import workerFarm from "worker-farm";
import { buildBenchmark } from "./build-benchmark"

const DEFAULT_FARM_OPTS = {
maxConcurrentWorkers: isCI ? 2 : require('os').cpus().length,
Expand All @@ -17,7 +18,17 @@ const DEFAULT_FARM_OPTS = {

interface ChildMessage { type: string, benchmarkPath: string, message: string }

export async function buildBenchmarks(benchmarks: string[], projectConfig: FrozenProjectConfig, globalConfig: FrozenGlobalConfig, buildLogStream: BuildOutputStream): Promise<BuildConfig[]> {
async function runInBand(benchmarks: string[], projectConfig: FrozenProjectConfig, globalConfig: FrozenGlobalConfig, buildLogStream: BuildOutputStream): Promise<BuildConfig[]> {
const benchmarkResults: BuildConfig[] = [];
for (const benchmark of benchmarks) {
const result = await buildBenchmark(benchmark,projectConfig, globalConfig, buildLogStream);
benchmarkResults.push(result);
}

return benchmarkResults;
}

function runInWorkers(benchmarks: string[], projectConfig: FrozenProjectConfig, globalConfig: FrozenGlobalConfig, buildLogStream: BuildOutputStream): Promise<BuildConfig[]> {
const opts = {
...DEFAULT_FARM_OPTS,
onChild: (child: NodeJS.Process) => {
Expand Down Expand Up @@ -61,3 +72,11 @@ export async function buildBenchmarks(benchmarks: string[], projectConfig: Froze
});
});
}

export function buildBenchmarks(benchmarks: string[], projectConfig: FrozenProjectConfig, globalConfig: FrozenGlobalConfig, buildLogStream: BuildOutputStream): Promise<BuildConfig[]> {
if (globalConfig.runInBand) {
return runInBand(benchmarks, projectConfig, globalConfig, buildLogStream);
} else {
return runInWorkers(benchmarks, projectConfig, globalConfig, buildLogStream);
}
}
8 changes: 7 additions & 1 deletion packages/@best/cli/src/cli/args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ export const options: { [key: string]: Options } = {
description: 'Displays calculated globalConfig and project configs',
type: 'boolean',
},
runInBand: {
default: undefined,
description: "Run in the main thread in one core (no paralellism)",
type: 'boolean'
},
externalStorage: {
default: undefined,
description:
Expand Down Expand Up @@ -120,7 +125,7 @@ export const options: { [key: string]: Options } = {
};

export function normalize(args: { [x: string]: any; _: string[]; $0: string }): CliConfig {
const { _, help, clearCache, clearResults, showConfigs, disableInteractive, gitIntegration, generateHTML, useHttp, externalStorage, runner, runnerConfig, config, projects, iterations, compareStats, dbAdapter, dbURI, runInBatch } = args;
const { _, help, clearCache, clearResults, showConfigs, disableInteractive, gitIntegration, generateHTML, useHttp, externalStorage, runner, runnerConfig, config, projects, iterations, compareStats, dbAdapter, dbURI, runInBatch, runInBand } = args;

return {
_,
Expand All @@ -129,6 +134,7 @@ export function normalize(args: { [x: string]: any; _: string[]; $0: string }):
clearResults: Boolean(clearResults),
useHttp: Boolean(useHttp),
showConfigs: Boolean(showConfigs),
runInBand: Boolean(runInBand),
disableInteractive,
runInBatch,
gitIntegration,
Expand Down
1 change: 1 addition & 0 deletions packages/@best/config/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ function generateProjectConfigs(options: NormalizedConfig, isRoot: boolean, gitI
projects: options.projects,
rootDir: options.rootDir,
rootProjectName: options.projectName,
runInBand: options.runInBand,
nonFlagArgs: options.nonFlagArgs,
gitInfo: gitInfo,
isInteractive: options.isInteractive,
Expand Down
1 change: 1 addition & 0 deletions packages/@best/config/src/utils/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const defaultOptions = {
}],
plugins: [],
projects: [],
runInBand: false,
runnerConfig: {},
benchmarkEnvironment: 'production',
benchmarkMaxDuration: 1000 * 15, // 15s
Expand Down
3 changes: 3 additions & 0 deletions packages/@best/config/src/utils/normalize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ function setCliOptionOverrides(initialOptions: UserConfig, argsCLI: CliConfig):
case 'runInBatch':
options.runInBatch = !!argsCLI[key];
break;
case 'runInBand':
options.runInBand = !!argsCLI[key];
break;
case 'projects':
if (argsCLI.projects && argsCLI.projects.length) {
options.projects = argsCLI.projects;
Expand Down
43 changes: 27 additions & 16 deletions packages/@best/console-stream/src/build-stream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
*/

import path from "path";
import { isInteractive as globaIsInteractive, clearLine } from "@best/utils";
import { isInteractive as globaIsInteractive } from "@best/utils";
import chalk from "chalk";
import trimPath from "./utils/trim-path";
import countEOL from "./utils/count-eod";
import { ProxiedStream, proxyStream } from "./utils/proxy-stream";

interface ProjectBenchmarkTests {
config: { projectName: string; rootDir: string },
Expand Down Expand Up @@ -49,17 +50,21 @@ function printProjectName(projectName: string) {
}

export default class BuildOutputStream {
stdout: NodeJS.WriteStream;
stdoutColumns: number;
stdoutWrite: Function;
isInteractive: boolean;
_streamBuffer: string = '';
_state: AllBencharkState;
_innerLog: string = '';
_scheduled: NodeJS.Timeout | null = null;
_proxiedStream: ProxiedStream;

constructor(buildConfig: ListProjectBenchmarkTests, stream: NodeJS.WriteStream, isInteractive?: boolean) {
this.stdout = stream;
this.stdoutColumns = stream.columns || 80;
this.stdoutWrite = stream.write.bind(stream);
this.isInteractive = isInteractive !== undefined ? isInteractive : globaIsInteractive;
this._state = this.initState(buildConfig);
this._proxiedStream = proxyStream(stream, this.isInteractive);
}

initState(buildConfig: ListProjectBenchmarkTests) {
Expand All @@ -82,14 +87,19 @@ export default class BuildOutputStream {
if (lines) {
buffer = '\r\x1B[K\r\x1B[1A'.repeat(lines);
}
clearLine(this.stdout);
this.stdout.write(buffer);

if (this.isInteractive) {
// clear last line
this.stdoutWrite('\x1b[999D\x1b[K');
}

this.stdoutWrite(buffer);
this._streamBuffer = '';
}

writeBufferStream(str: string) {
this._streamBuffer += str;
this.stdout.write(str);
this.stdoutWrite(str);
}

updateBenchmarkState(benchmarkPath: string, state: State) {
Expand All @@ -107,7 +117,7 @@ export default class BuildOutputStream {
} else {
const benchmarkState = this._state.get(benchmarkPath);
if (benchmarkState) {
this.stdout.write(this.printBenchmark(benchmarkState));
this.stdoutWrite(this.printBenchmark(benchmarkState));
}
}
}
Expand All @@ -121,23 +131,23 @@ export default class BuildOutputStream {
}
}

printBenchmark({ state, projectName, displayPath }:{ state: State, projectName: string, displayPath: string }) {
const columns = this.stdout.columns || 80;
printBenchmark({ state, projectName, displayPath }:{ state: State, projectName: string, displayPath: string }, streamProxyBuffer?: string) {
const columns = this.stdoutColumns;
const overflow = columns - (state.length + projectName.length + displayPath.length + /* for padding */ 14);
const hasOverflow = overflow < 0;

const ansiState = printState(state);
const ansiProjectName = printProjectName(projectName);
const ansiDisplayname = printDisplayName(displayPath, hasOverflow ? Math.abs(overflow): 0);

return `${ansiState} ${ansiProjectName} ${ansiDisplayname}\n`;
const proxiedBuffer = streamProxyBuffer ? `Buffered console logs:\n ${streamProxyBuffer}` : '';
return `${ansiState} ${ansiProjectName} ${ansiDisplayname}\n${proxiedBuffer}`;
}

updateStream() {
const innerState = this._innerLog;
let buffer = INIT_MSG;
for (const { state, displayPath, projectName } of this._state.values()) {
buffer += this.printBenchmark({ state, displayPath, projectName });
buffer += this.printBenchmark({ state, displayPath, projectName }, this._proxiedStream.readBuffer());
}

if (innerState) {
Expand All @@ -157,7 +167,7 @@ export default class BuildOutputStream {
} else {
const benchmarkState = this._state.get(benchmarkPath);
if (benchmarkState) {
this.stdout.write(this.printBenchmark(benchmarkState) + '\n');
this.stdoutWrite(this.printBenchmark(benchmarkState, this._proxiedStream.readBuffer()) + '\n');
}
}
}
Expand All @@ -167,19 +177,20 @@ export default class BuildOutputStream {
if (this.isInteractive) {
this.scheduleUpdate();
} else {
this.stdout.write(` :: ${message}\n`);
this.stdoutWrite(` :: ${message}\n`);
}
}

init() {
if (this.isInteractive) {
this.updateStream();
} else {
this.stdout.write(INIT_MSG);
this.stdoutWrite(INIT_MSG);
}
}

finish() {
this._proxiedStream.unproxyStream();
if (this._scheduled) {
clearTimeout(this._scheduled);
this._scheduled = null;
Expand All @@ -188,7 +199,7 @@ export default class BuildOutputStream {
if (this.isInteractive) {
this.updateStream();
} else {
this.stdout.write('\n');
this.stdoutWrite('\n');
}
}
}
Loading

0 comments on commit e739ee4

Please sign in to comment.