Fix app rename failing with "port is taken" error
renameApp() killed the old process with .kill() but didn't wait for it to actually exit before restarting on the same port. The OS still had the port bound, causing the new process to fail with "port is taken". Additionally, the old process's exit handler would fire after the rename and corrupt the app's state—releasing the new process's port, setting state to 'invalid', and nullifying the proc reference. Fix by: - Making renameApp async and awaiting proc.exited before proceeding - Guarding the exit handler to bail out when a newer process has taken over https://claude.ai/code/session_01W9GF8Cy7T6V2rnVcoNd1Nc
This commit is contained in:
parent
9c128eaddc
commit
2f4d609290
|
|
@ -229,7 +229,7 @@ router.post('/:app/rename', async c => {
|
|||
|
||||
if (!newName) return c.json({ ok: false, error: 'New name is required' }, 400)
|
||||
|
||||
const result = renameApp(appName, newName)
|
||||
const result = await renameApp(appName, newName)
|
||||
if (!result.ok) return c.json(result, 400)
|
||||
|
||||
return c.json({ ok: true, name: newName })
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ export function registerApp(dir: string) {
|
|||
}
|
||||
}
|
||||
|
||||
export function renameApp(oldName: string, newName: string): { ok: boolean, error?: string } {
|
||||
export async function renameApp(oldName: string, newName: string): Promise<{ ok: boolean, error?: string }> {
|
||||
const app = _apps.get(oldName)
|
||||
if (!app) return { ok: false, error: 'App not found' }
|
||||
|
||||
|
|
@ -155,15 +155,13 @@ export function renameApp(oldName: string, newName: string): { ok: boolean, erro
|
|||
const oldPath = join(APPS_DIR, oldName)
|
||||
const newPath = join(APPS_DIR, newName)
|
||||
|
||||
// Stop the app if running
|
||||
// Stop the app and wait for process to fully exit so the port is freed
|
||||
const wasRunning = app.state === 'running'
|
||||
if (wasRunning) {
|
||||
const proc = app.proc
|
||||
clearTimers(app)
|
||||
app.proc?.kill()
|
||||
app.proc = undefined
|
||||
if (app.port) releasePort(app.port)
|
||||
app.port = undefined
|
||||
app.started = undefined
|
||||
if (proc) await proc.exited
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
@ -681,6 +679,10 @@ async function runApp(dir: string, port: number) {
|
|||
|
||||
// Handle process exit
|
||||
proc.exited.then(code => {
|
||||
// If the app has moved on (e.g. renamed and restarted), this is a
|
||||
// stale exit handler — don't touch current app state or ports
|
||||
if (app.proc && app.proc !== proc) return
|
||||
|
||||
// Clear all timers
|
||||
clearTimers(app)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user