0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-03-04 01:44:26 -05:00

refactor: cleanup compiler runtimes (#4230)

- Cleanup "tsCompilerOnMessage" by factoring out separate methods for each 
  request type:
    * "compile"
    * "runtimeCompile"
    * "runtimeTranspile"
- Simplify control flow of compiler workers by a) no longer calling "close()" in worker runtime after a
single message; b) explicitly shutting down worker from host after a single message

Co-authored-by: Ryan Dahl <ry@tinyclouds.org>
This commit is contained in:
Bartek Iwańczuk 2020-03-05 11:13:10 +01:00 committed by GitHub
parent 159de0245d
commit 52b96fc22a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 270 additions and 253 deletions

View file

@ -620,11 +620,7 @@ async fn execute_in_thread(
WorkerEvent::Message(buf) => Ok(buf), WorkerEvent::Message(buf) => Ok(buf),
WorkerEvent::Error(error) => Err(error), WorkerEvent::Error(error) => Err(error),
}?; }?;
// Compiler worker finishes after one request // Shutdown worker and wait for thread to finish
// so we should receive signal that channel was closed.
// Then close worker's channel and join the thread.
let event = handle.get_event().await;
assert!(event.is_none());
handle.sender.close_channel(); handle.sender.close_channel();
join_handle.join().unwrap(); join_handle.join().unwrap();
Ok(buf) Ok(buf)

View file

@ -134,11 +134,7 @@ async fn execute_in_thread(
WorkerEvent::Message(buf) => Ok(buf), WorkerEvent::Message(buf) => Ok(buf),
WorkerEvent::Error(error) => Err(error), WorkerEvent::Error(error) => Err(error),
}?; }?;
// Compiler worker finishes after one request // Shutdown worker and wait for thread to finish
// so we should receive signal that channel was closed.
// Then close worker's channel and join the thread.
let event = handle.get_event().await;
assert!(event.is_none());
handle.sender.close_channel(); handle.sender.close_channel();
join_handle.join().unwrap(); join_handle.join().unwrap();
Ok(buf) Ok(buf)

View file

@ -36,7 +36,7 @@ import {
WriteFileState, WriteFileState,
processConfigureResponse processConfigureResponse
} from "./compiler_util.ts"; } from "./compiler_util.ts";
import { Diagnostic } from "./diagnostics.ts"; import { Diagnostic, DiagnosticItem } from "./diagnostics.ts";
import { fromTypeScriptDiagnostic } from "./diagnostics_util.ts"; import { fromTypeScriptDiagnostic } from "./diagnostics_util.ts";
import { assert } from "./util.ts"; import { assert } from "./util.ts";
import * as util from "./util.ts"; import * as util from "./util.ts";
@ -81,25 +81,19 @@ interface CompileResult {
diagnostics?: Diagnostic; diagnostics?: Diagnostic;
} }
// TODO(bartlomieju): refactor this function into multiple functions type RuntimeCompileResult = [
// per CompilerRequestType undefined | DiagnosticItem[],
async function tsCompilerOnMessage({ Record<string, string>
data: request ];
}: {
data: CompilerRequest; type RuntimeBundleResult = [undefined | DiagnosticItem[], string];
}): Promise<void> {
switch (request.type) { /** `Compile` are requests from the internals of Deno; eg. used when
// `Compile` are requests from the internals to Deno, generated by both * the `run` or `bundle` subcommand is used. */
// the `run` and `bundle` sub command. async function compile(
case CompilerRequestType.Compile: { request: CompilerRequestCompile
const { ): Promise<CompileResult> {
bundle, const { bundle, config, configPath, outFile, rootNames, target } = request;
config,
configPath,
outFile,
rootNames,
target
} = request;
util.log(">>> compile start", { util.log(">>> compile start", {
rootNames, rootNames,
type: CompilerRequestType[request.type] type: CompilerRequestType[request.type]
@ -182,18 +176,26 @@ async function tsCompilerOnMessage({
? fromTypeScriptDiagnostic(diagnostics) ? fromTypeScriptDiagnostic(diagnostics)
: undefined : undefined
}; };
globalThis.postMessage(result);
util.log("<<< compile end", { util.log("<<< compile end", {
rootNames, rootNames,
type: CompilerRequestType[request.type] type: CompilerRequestType[request.type]
}); });
break;
} return result;
case CompilerRequestType.RuntimeCompile: { }
// `RuntimeCompile` are requests from a runtime user, both compiles and
// bundles. The process is similar to a request from the privileged /**`RuntimeCompile` are requests from a runtime user; it can be both
// side, but also returns the output to the on message. * "compile" and "bundle".
*
* The process is similar to a request from the privileged
* side, but unline `compile`, `runtimeCompile` allows to specify
* additional file mappings which can be used instead of relying
* on Deno defaults.
*/
async function runtimeCompile(
request: CompilerRequestRuntimeCompile
): Promise<RuntimeCompileResult | RuntimeBundleResult> {
const { rootName, sources, options, bundle, target } = request; const { rootName, sources, options, bundle, target } = request;
util.log(">>> runtime compile start", { util.log(">>> runtime compile start", {
@ -204,9 +206,7 @@ async function tsCompilerOnMessage({
// resolve the root name, if there are sources, the root name does not // resolve the root name, if there are sources, the root name does not
// get resolved // get resolved
const resolvedRootName = sources const resolvedRootName = sources ? rootName : resolveModules([rootName])[0];
? rootName
: resolveModules([rootName])[0];
// if there are options, convert them into TypeScript compiler options, // if there are options, convert them into TypeScript compiler options,
// and resolve any external file references // and resolve any external file references
@ -293,13 +293,6 @@ async function tsCompilerOnMessage({
const emitResult = program.emit(); const emitResult = program.emit();
assert(emitResult.emitSkipped === false, "Unexpected skip of the emit."); assert(emitResult.emitSkipped === false, "Unexpected skip of the emit.");
const result = [
diagnostics.length
? fromTypeScriptDiagnostic(diagnostics).items
: undefined,
bundle ? state.emitBundle : state.emitMap
];
globalThis.postMessage(result);
assert(state.emitMap); assert(state.emitMap);
util.log("<<< runtime compile finish", { util.log("<<< runtime compile finish", {
@ -309,9 +302,20 @@ async function tsCompilerOnMessage({
emitMap: Object.keys(state.emitMap) emitMap: Object.keys(state.emitMap)
}); });
break; const maybeDiagnostics = diagnostics.length
? fromTypeScriptDiagnostic(diagnostics).items
: undefined;
if (bundle) {
return [maybeDiagnostics, state.emitBundle] as RuntimeBundleResult;
} else {
return [maybeDiagnostics, state.emitMap] as RuntimeCompileResult;
} }
case CompilerRequestType.RuntimeTranspile: { }
async function runtimeTranspile(
request: CompilerRequestRuntimeTranspile
): Promise<Record<string, TranspileOnlyResult>> {
const result: Record<string, TranspileOnlyResult> = {}; const result: Record<string, TranspileOnlyResult> = {};
const { sources, options } = request; const { sources, options } = request;
const compilerOptions = options const compilerOptions = options
@ -332,8 +336,32 @@ async function tsCompilerOnMessage({
); );
result[fileName] = { source, map }; result[fileName] = { source, map };
} }
globalThis.postMessage(result); return result;
}
async function tsCompilerOnMessage({
data: request
}: {
data: CompilerRequest;
}): Promise<void> {
switch (request.type) {
case CompilerRequestType.Compile: {
const result = await compile(request as CompilerRequestCompile);
globalThis.postMessage(result);
break;
}
case CompilerRequestType.RuntimeCompile: {
const result = await runtimeCompile(
request as CompilerRequestRuntimeCompile
);
globalThis.postMessage(result);
break;
}
case CompilerRequestType.RuntimeTranspile: {
const result = await runtimeTranspile(
request as CompilerRequestRuntimeTranspile
);
globalThis.postMessage(result);
break; break;
} }
default: default:
@ -343,9 +371,7 @@ async function tsCompilerOnMessage({
} (${CompilerRequestType[(request as CompilerRequest).type]})` } (${CompilerRequestType[(request as CompilerRequest).type]})`
); );
} }
// Currently Rust shuts down worker after single request
// The compiler isolate exits after a single message.
globalThis.close();
} }
async function wasmCompilerOnMessage({ async function wasmCompilerOnMessage({
@ -372,8 +398,7 @@ async function wasmCompilerOnMessage({
util.log("<<< WASM compile end"); util.log("<<< WASM compile end");
// The compiler isolate exits after a single message. // Currently Rust shuts down worker after single request
globalThis.close();
} }
function bootstrapTsCompilerRuntime(): void { function bootstrapTsCompilerRuntime(): void {