Skip to content

Commit b638d89

Browse files
committed
Cleanup process manager. Remove unused env vars.
1 parent 17cd5df commit b638d89

File tree

4 files changed

+118
-117
lines changed

4 files changed

+118
-117
lines changed

wasp-app-runner/src/db/postgres.ts

+18-19
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { createHash } from "crypto";
22

33
import type { SetupDbFn } from "./types.js";
44
import { log } from "../logging.js";
5-
import { processManager } from "../process.js";
5+
import { spawnAndCollectOutput } from "../process.js";
66
import { Branded } from "../types.js";
77

88
type ContainerName = Branded<string, "ContainerName">;
@@ -67,22 +67,21 @@ async function startPostgresContainerAndWaitUntilReady(
6767

6868
log("postgres", "info", "Starting the PostgreSQL container...");
6969

70-
processManager
71-
.spawnAndCollectStdout({
72-
name: "create-postgres-container",
73-
cmd: "docker",
74-
args: [
75-
"run",
76-
"--name",
77-
containerName,
78-
"-p",
79-
`${port}:5432`,
80-
"-e",
81-
`POSTGRES_PASSWORD=${password}`,
82-
`--rm`,
83-
image,
84-
],
85-
})
70+
spawnAndCollectOutput({
71+
name: "create-postgres-container",
72+
cmd: "docker",
73+
args: [
74+
"run",
75+
"--name",
76+
containerName,
77+
"-p",
78+
`${port}:5432`,
79+
"-e",
80+
`POSTGRES_PASSWORD=${password}`,
81+
`--rm`,
82+
image,
83+
],
84+
})
8685
// If we awaited here, we would block the main thread indefinitely.
8786
.then(({ exitCode, stderrData }) => {
8887
if (exitCode !== 0) {
@@ -130,7 +129,7 @@ async function waitForPostgresReady(
130129
async function checkIfPostgresIsReady(
131130
containerName: ContainerName
132131
): Promise<boolean> {
133-
const { exitCode } = await processManager.spawnAndCollectStdout({
132+
const { exitCode } = await spawnAndCollectOutput({
134133
name: "postgres-readiness-check",
135134
cmd: "docker",
136135
args: ["exec", containerName, "pg_isready", "-U", "postgres"],
@@ -159,7 +158,7 @@ async function ensureDockerIsRunning(): Promise<void> {
159158
}
160159

161160
async function checkIfDockerIsRunning(): Promise<boolean> {
162-
const { exitCode } = await processManager.spawnAndCollectStdout({
161+
const { exitCode } = await spawnAndCollectOutput({
163162
name: "docker-health-check",
164163
cmd: "docker",
165164
args: ["info"],

wasp-app-runner/src/process.ts

+92-88
Original file line numberDiff line numberDiff line change
@@ -3,122 +3,126 @@ import { ChildProcess, spawn } from "child_process";
33
import { log } from "./logging.js";
44
import type { EnvVars } from "./types.js";
55

6-
export const processManager = setupProcessManager();
7-
86
type SpawnOptions = {
97
name: string;
108
cmd: string;
119
args: string[];
1210
cwd?: string;
1311
};
1412

15-
function setupProcessManager() {
16-
const children: ChildProcess[] = [];
13+
class ChildProcessManager {
14+
private children: ChildProcess[] = [];
15+
16+
constructor() {
17+
process.on("SIGINT", () => this.cleanExit("SIGINT"));
18+
process.on("SIGTERM", () => this.cleanExit("SIGTERM"));
19+
}
1720

18-
function addChild(child: ChildProcess) {
19-
children.push(child);
21+
addChild(child: ChildProcess) {
22+
this.children.push(child);
2023
}
2124

22-
function removeChild(proc: ChildProcess) {
23-
const index = children.indexOf(proc);
25+
removeChild(proc: ChildProcess) {
26+
const index = this.children.indexOf(proc);
2427
if (index !== -1) {
25-
children.splice(index, 1);
28+
this.children.splice(index, 1);
2629
}
2730
}
2831

29-
const cleanExit = (reason: string) => {
30-
log("shutdown", "warn", `Received ${reason}. Cleaning up...`);
31-
children.forEach((child) => {
32+
private cleanExit(reason: string) {
33+
log("shutdown", "info", `Received ${reason}. Cleaning up...`);
34+
this.children.forEach((child) => {
3235
if (!child.killed) {
3336
child.kill();
3437
}
3538
});
3639
process.exit();
37-
};
38-
39-
process.on("SIGINT", () => cleanExit("SIGINT"));
40-
process.on("SIGTERM", () => cleanExit("SIGTERM"));
41-
42-
function spawnWithLog({
43-
name,
44-
cmd,
45-
args,
46-
cwd,
47-
extraEnv = {},
48-
}: SpawnOptions & {
49-
extraEnv?: EnvVars;
50-
}): Promise<number | null> {
51-
return new Promise((resolve, reject) => {
52-
const proc = spawn(cmd, args, {
53-
cwd,
54-
env: { ...process.env, ...extraEnv },
55-
stdio: ["ignore", "pipe", "pipe"],
56-
});
57-
addChild(proc);
58-
59-
const handleStream = (
60-
stream: NodeJS.ReadableStream,
61-
type: "stdout" | "stderr"
62-
) => {
63-
const rl = readline.createInterface({
64-
input: stream,
65-
crlfDelay: Infinity,
66-
});
67-
68-
rl.on("line", (line) => {
69-
log(name, type === "stderr" ? "error" : "info", line);
70-
});
71-
};
40+
}
41+
}
7242

73-
handleStream(proc.stdout, "stdout");
74-
handleStream(proc.stderr, "stderr");
43+
const childProcessManager = new ChildProcessManager();
44+
45+
export function spawnWithLog({
46+
name,
47+
cmd,
48+
args,
49+
cwd,
50+
extraEnv = {},
51+
}: SpawnOptions & {
52+
extraEnv?: EnvVars;
53+
}): Promise<{ exitCode: number | null }> {
54+
return new Promise((resolve, reject) => {
55+
const proc = spawn(cmd, args, {
56+
cwd,
57+
env: { ...process.env, ...extraEnv },
58+
stdio: ["ignore", "pipe", "pipe"],
59+
});
60+
childProcessManager.addChild(proc);
7561

76-
proc.on("error", (err) => {
77-
log(name, "error", `Process error: ${err.message}`);
78-
reject(err);
79-
});
62+
readStreamLines(proc.stdout, (line) => log(name, "info", line));
63+
readStreamLines(proc.stderr, (line) => log(name, "error", line));
8064

81-
proc.on("close", (code) => {
82-
removeChild(proc);
83-
if (code === 0) {
84-
log(name, "success", "Process completed successfully");
85-
resolve(code);
86-
} else {
87-
log(name, "error", `Process exited with code ${code}`);
88-
reject(code);
89-
}
90-
});
65+
proc.on("error", (err) => {
66+
log(name, "error", `Process error: ${err.message}`);
67+
reject(err);
9168
});
92-
}
9369

94-
function spawnAndCollectStdout({ cmd, args, cwd }: SpawnOptions): Promise<{
95-
exitCode: number | null;
96-
stdoutData: string;
97-
stderrData: string;
98-
}> {
99-
let stdoutData = "";
100-
let stderrData = "";
101-
return new Promise((resolve, reject) => {
102-
const proc = spawn(cmd, args, {
103-
cwd,
104-
});
105-
addChild(proc);
106-
107-
proc.stdout.on("data", (data) => (stdoutData += data));
108-
proc.stderr.on("data", (data) => (stderrData += data));
109-
proc.on("close", (exitCode) => {
110-
removeChild(proc);
70+
proc.on("close", (exitCode) => {
71+
childProcessManager.removeChild(proc);
72+
if (exitCode === 0) {
73+
log(name, "success", "Process completed successfully");
11174
resolve({
11275
exitCode,
113-
stdoutData,
114-
stderrData,
11576
});
77+
} else {
78+
log(name, "error", `Process exited with code ${exitCode}`);
79+
reject({
80+
exitCode,
81+
});
82+
}
83+
});
84+
});
85+
}
86+
87+
export function spawnAndCollectOutput({
88+
cmd,
89+
args,
90+
cwd,
91+
}: SpawnOptions): Promise<{
92+
exitCode: number | null;
93+
stdoutData: string;
94+
stderrData: string;
95+
}> {
96+
let stdoutData = "";
97+
let stderrData = "";
98+
return new Promise((resolve) => {
99+
const proc = spawn(cmd, args, {
100+
cwd,
101+
});
102+
childProcessManager.addChild(proc);
103+
104+
readStreamLines(proc.stdout, (line) => (stdoutData += line + "\n"));
105+
readStreamLines(proc.stderr, (line) => (stderrData += line + "\n"));
106+
107+
proc.on("close", (exitCode) => {
108+
childProcessManager.removeChild(proc);
109+
resolve({
110+
exitCode,
111+
stdoutData,
112+
stderrData,
116113
});
117114
});
118-
}
115+
});
116+
}
117+
118+
function readStreamLines(
119+
stream: NodeJS.ReadableStream,
120+
callback: (line: string) => void
121+
) {
122+
const rl = readline.createInterface({
123+
input: stream,
124+
crlfDelay: Infinity,
125+
});
119126

120-
return {
121-
spawnWithLog,
122-
spawnAndCollectStdout,
123-
};
127+
rl.on("line", callback);
124128
}

wasp-app-runner/src/waspCli.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { stripVTControlCharacters } from "node:util";
22

33
import { log } from "./logging.js";
44
import { getWaspcDirAbsPath } from "./path.js";
5-
import { processManager } from "./process.js";
5+
import { spawnWithLog, spawnAndCollectOutput } from "./process.js";
66
import { DbType } from "./db/index.js";
77
import type { EnvVars } from "./types.js";
88

@@ -14,8 +14,8 @@ export function migrateDb({
1414
waspCliCmd: string;
1515
pathToApp: string;
1616
extraEnv: EnvVars;
17-
}): Promise<number | null> {
18-
return processManager.spawnWithLog({
17+
}): Promise<{ exitCode: number | null }> {
18+
return spawnWithLog({
1919
name: "migrate-db",
2020
cmd: waspCliCmd,
2121
args: ["db", "migrate-dev"],
@@ -32,8 +32,8 @@ export function startApp({
3232
waspCliCmd: string;
3333
pathToApp: string;
3434
extraEnv: EnvVars;
35-
}): Promise<number | null> {
36-
return processManager.spawnWithLog({
35+
}): Promise<{ exitCode: number | null }> {
36+
return spawnWithLog({
3737
name: "start-app",
3838
cmd: waspCliCmd,
3939
args: ["start"],
@@ -52,7 +52,7 @@ export async function getAppInfo({
5252
appName: string;
5353
dbType: DbType;
5454
}> {
55-
const { stdoutData, exitCode } = await processManager.spawnAndCollectStdout({
55+
const { stdoutData, exitCode } = await spawnAndCollectOutput({
5656
name: "get-app-info",
5757
cmd: waspCliCmd,
5858
args: ["info"],
@@ -93,10 +93,10 @@ export async function getAppInfo({
9393
};
9494
}
9595

96-
export async function installWaspCli(): Promise<number | null> {
96+
export async function installWaspCli(): Promise<{ exitCode: number | null }> {
9797
log("install-wasp-cli", "info", "Installing Wasp CLI globally...");
9898

99-
return processManager.spawnWithLog({
99+
return spawnWithLog({
100100
name: "install-wasp-cli",
101101
cmd: "cabal",
102102
args: ["install", "--overwrite-policy=always"],

waspc/examples/todoApp/.env.client.headless

-2
This file was deleted.

0 commit comments

Comments
 (0)