Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
},
"dependencies": {
"@clerk/backend": "^1.34.0",
"@gitwit/templates": "*",
"@gitwit/db": "*",
"@octokit/core": "^7.0.3",
"dotenv": "^16.6.1",
Expand Down
56 changes: 56 additions & 0 deletions lib/services/Project.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { templateConfigs } from "@gitwit/templates"
import { Sandbox as Container } from "e2b"
import { CONTAINER_TIMEOUT } from "../utils/constants"
import { FileManager } from "./FileManager"
Expand All @@ -24,6 +25,61 @@ export class Project {
this.projectId = projectId
}

/**
* Kill all known dev server processes in the container (e.g. npm run dev, yarn dev, pnpm dev, vite, next, etc.)
*/
async killDevServers(): Promise<void> {
if (!this.container) return
// Gather all dev server patterns (template + common)
const patterns = [
this.type && templateConfigs[this.type]?.runCommand,
"vite",
"next",
"nodemon",
"webpack serve",
"parcel",
"gulp",
"python -m http.server",
"node ",
"npm ",
].filter(Boolean)

let psOutput = ""
try {
const result = await this.container.commands.run("ps aux")
psOutput = result.stdout || ""
} catch {}

const lines = psOutput.split("\n")
const killed: string[] = []
const seenPids = new Set<string>()

for (const line of lines) {
for (const pattern of patterns) {
if (pattern && line.includes(pattern)) {
const parts = line.trim().split(/\s+/)
const pid = parts[1]
if (pid && pid !== "PID" && !seenPids.has(pid)) {
try {
await this.container.commands.run(`kill -9 ${pid}`)
killed.push(`${pattern} (pid ${pid})`)
seenPids.add(pid)
} catch {}
}
}
}
}

if (killed.length) {
console.log(
`[killDevServers] Killed processes for project ${this.projectId}:\n${killed.join("\n")}`,
)
} else {
console.log(
`[killDevServers] No dev server processes found to kill for project ${this.projectId}`,
)
}
}
async createContainer(): Promise<Container> {
console.log("Creating container for ", this.projectId)
const templateTypes = ["vanillajs", "reactjs", "nextjs", "streamlit", "php"]
Expand Down
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
"db:studio": "npm run studio -w db",
"db:studio:prod": "NODE_ENV=production npm run studio -w db",
"dev:deps": "concurrently -k -n LIB,DB -c yellow,magenta \"npm run dev -w lib\" \"npm run dev -w db\"",
"dev": "npm run build:deps && concurrently -k -n WEB,SERVER,AI -c blue,green,cyan \"npm run dev -w web\" \"npm run dev -w server\" \"npm run dev -w ai\"",
"dev:web": "npm run build:deps && npm run dev -w web",
"dev:server": "npm run build:deps && npm run dev -w server",
"dev": "concurrently -k -n LIB,DB,WEB,SERVER,AI -c yellow,magenta,blue,green,cyan \"npm run dev -w lib\" \"npm run dev -w db\" \"npm run dev -w web\" \"npm run dev -w server\" \"npm run dev -w ai\"",
"dev:web": "concurrently -k -n LIB,DB,WEB -c yellow,magenta,blue \"npm run dev -w lib\" \"npm run dev -w db\" \"npm run dev -w web\"",
"dev:server": "concurrently -k -n LIB,DB,SERVER -c yellow,magenta,green \"npm run dev -w lib\" \"npm run dev -w db\" \"npm run dev -w server\"",
"dev:watch": "concurrently -k -n LIB,DB,WEB,SERVER -c yellow,magenta,blue,green \"npm run dev -w lib\" \"npm run dev -w db\" \"npm run dev -w web\" \"npm run dev -w server\"",
"start": "concurrently -k \"npm start -w web\" \"npm start -w server\"",
"start:web": "npm start -w web",
Expand Down
7 changes: 4 additions & 3 deletions server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ const gitClient =
process.env.DOKKU_HOST && process.env.DOKKU_KEY
? new SecureGitClient(
`dokku@${process.env.DOKKU_HOST}`,
process.env.DOKKU_KEY
process.env.DOKKU_KEY,
)
: null

Expand Down Expand Up @@ -123,7 +123,7 @@ io.on("connection", async (socket) => {
{
dokkuClient,
gitClient,
}
},
)

// For each event handler, listen on the socket for that event
Expand All @@ -138,7 +138,7 @@ io.on("connection", async (socket) => {
} catch (e: any) {
handleErrors(`Error processing event "${event}":`, e, socket)
}
}
},
)
})

Expand All @@ -149,6 +149,7 @@ io.on("connection", async (socket) => {
try {
// Deregister the connection
connections.removeConnectionForProject(socket, data.projectId)
await project.killDevServers()
} catch (e: any) {
handleErrors("Error disconnecting:", e, socket)
}
Expand Down